mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-02 00:18:17 +00:00
Upload button (dev only) can now be Enabled via User Attributes (#654)
Co-authored-by: wil <wil@storyteller.ai>
This commit is contained in:
1 parent
b7f65a9145
commit
ecf27daa15
11 files changed
+82
-64
No files matched your search
+2
-24
@@ -1,34 +1,12 @@
|
||||
import { RemixBrowser } from "@remix-run/react";
|
||||
import { startTransition, StrictMode, useEffect } from "react";
|
||||
import { startTransition, StrictMode } from "react";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
import { posthog } from "posthog-js";
|
||||
import { PostHogProvider } from "posthog-js/react";
|
||||
import EnvironmentVariables from "~/Classes/EnvironmentVariables";
|
||||
|
||||
function PosthogInit() {
|
||||
useEffect(() => {
|
||||
const data = EnvironmentVariables.values;
|
||||
|
||||
const apiKey = data.REACT_APP_PUBLIC_POSTHOG_KEY as string;
|
||||
posthog.init(apiKey, {
|
||||
//HACK: This is the default host from Netlify, but need to figure out why it isn't working on prod.
|
||||
// api_host: data.DEPLOY_PRIME_URL + "/ingest" as string,
|
||||
api_host: "https://studio.storyteller.ai/ingest" as string,
|
||||
ui_host: data.REACT_APP_PUBLIC_POSTHOG_UI as string,
|
||||
});
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
startTransition(() => {
|
||||
hydrateRoot(
|
||||
document,
|
||||
<StrictMode>
|
||||
<PostHogProvider client={posthog}>
|
||||
<RemixBrowser />
|
||||
</PostHogProvider>
|
||||
<PosthogInit />
|
||||
<RemixBrowser />
|
||||
</StrictMode>,
|
||||
);
|
||||
});
|
||||
@@ -17,3 +17,10 @@ export enum AUTH_ERROR_FALLBACKS {
|
||||
GetSessionError = "Unknown Error During Get Session",
|
||||
Unauthorized = "User Unauthorized",
|
||||
}
|
||||
|
||||
export enum USER_FEATURE_FLAGS {
|
||||
EXPLORE_MEDIA = "explore_media",
|
||||
STUDIO = "studio",
|
||||
UPLOAD_3D = "upload_3d",
|
||||
VIDEO_STYLE_TRANSFER = "video_style_transfer",
|
||||
}
|
||||
+3
-1
@@ -1,3 +1,5 @@
|
||||
import { USER_FEATURE_FLAGS } from "~/enums";
|
||||
|
||||
export interface CoreInfo {
|
||||
default_avatar: {
|
||||
color_index: number;
|
||||
@@ -19,7 +21,7 @@ export interface UserInfo {
|
||||
|
||||
// Rollout feature flags
|
||||
can_access_studio: boolean;
|
||||
maybe_feature_flags: string[];
|
||||
maybe_feature_flags: USER_FEATURE_FLAGS[];
|
||||
|
||||
// Usage
|
||||
can_use_tts: boolean;
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from "./useUserObjects";
|
||||
export * from "./useFeaturedObjects";
|
||||
export * from "./useSearchFeaturedObjects";
|
||||
export * from "./useSearchUserObjects";
|
||||
export * from "./useFeatureFlags";
|
||||
@@ -0,0 +1,19 @@
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { authentication } from "~/signals";
|
||||
import { usePosthogFeatureFlag } from "~/hooks/usePosthogFeatureFlag";
|
||||
import { FeatureFlags } from "~/enums";
|
||||
|
||||
export const useFeatureFlags = () => {
|
||||
useSignals();
|
||||
|
||||
const showSearchObjectComponent = usePosthogFeatureFlag(
|
||||
FeatureFlags.SHOW_SEARCH_OBJECTS,
|
||||
);
|
||||
const showUploadButton =
|
||||
usePosthogFeatureFlag(FeatureFlags.DEV_ONLY) || authentication.canUpload3D;
|
||||
|
||||
return {
|
||||
showSearchObjectComponent,
|
||||
showUploadButton,
|
||||
};
|
||||
};
|
||||
+2
-6
@@ -4,7 +4,6 @@ import {
|
||||
ANIMATION_MIXAMO_FILE_TYPE,
|
||||
ANIMATION_MMD_FILE_TYPE,
|
||||
AssetFilterOption,
|
||||
FeatureFlags,
|
||||
FilterEngineCategories,
|
||||
MediaFileAnimationType,
|
||||
} from "~/enums";
|
||||
@@ -22,8 +21,8 @@ import {
|
||||
useFeaturedObjects,
|
||||
useSearchFeaturedObjects,
|
||||
useSearchUserdObjects,
|
||||
useFeatureFlags,
|
||||
} from "../../hooks";
|
||||
import { usePosthogFeatureFlag } from "~/hooks/usePosthogFeatureFlag";
|
||||
import {
|
||||
filterMixamoAnimations,
|
||||
filterMMDAnimations,
|
||||
@@ -39,10 +38,7 @@ export const AnimationsTab = ({
|
||||
animationType: MediaFileAnimationType;
|
||||
demoAnimationItems?: MediaItem[];
|
||||
}) => {
|
||||
const showSearchObjectComponent = usePosthogFeatureFlag(
|
||||
FeatureFlags.SHOW_SEARCH_OBJECTS,
|
||||
);
|
||||
const showUploadButton = usePosthogFeatureFlag(FeatureFlags.DEV_ONLY);
|
||||
const { showSearchObjectComponent, showUploadButton } = useFeatureFlags();
|
||||
|
||||
const [openUploadModal, setOpenUploadModal] = useState(false);
|
||||
|
||||
|
||||
+2
-6
@@ -4,7 +4,6 @@ import {
|
||||
AssetFilterOption,
|
||||
CHARACTER_MIXAMO_FILE_TYPE,
|
||||
CHARACTER_MMD_FILE_TYPE,
|
||||
FeatureFlags,
|
||||
FilterEngineCategories,
|
||||
MediaFileAnimationType,
|
||||
} from "~/enums";
|
||||
@@ -17,13 +16,13 @@ import {
|
||||
UploadModal,
|
||||
} from "~/components";
|
||||
import { ItemElements } from "~/pages/PageEnigma/comps/SidePanelTabs/sharedComps";
|
||||
import { usePosthogFeatureFlag } from "~/hooks/usePosthogFeatureFlag";
|
||||
import { isAnyStatusFetching } from "../../utilities";
|
||||
import {
|
||||
useUserObjects,
|
||||
useFeaturedObjects,
|
||||
useSearchFeaturedObjects,
|
||||
useSearchUserdObjects,
|
||||
useFeatureFlags,
|
||||
} from "../../hooks";
|
||||
import {
|
||||
filterMixamoCharacters,
|
||||
@@ -39,10 +38,7 @@ export const CharactersTab = ({
|
||||
animationType: MediaFileAnimationType;
|
||||
demoCharacterItems?: MediaItem[];
|
||||
}) => {
|
||||
const showSearchObjectComponent = usePosthogFeatureFlag(
|
||||
FeatureFlags.SHOW_SEARCH_OBJECTS,
|
||||
);
|
||||
const showUploadButton = usePosthogFeatureFlag(FeatureFlags.DEV_ONLY);
|
||||
const { showSearchObjectComponent, showUploadButton } = useFeatureFlags();
|
||||
|
||||
const [openUploadModal, setOpenUploadModal] = useState(false);
|
||||
|
||||
|
||||
+2
-6
@@ -4,7 +4,6 @@ import {
|
||||
AssetFilterOption,
|
||||
FilterEngineCategories,
|
||||
MediaFileAnimationType,
|
||||
FeatureFlags,
|
||||
} from "~/enums";
|
||||
import {
|
||||
Button,
|
||||
@@ -14,23 +13,20 @@ import {
|
||||
UploadModal,
|
||||
} from "~/components";
|
||||
import { ItemElements } from "~/pages/PageEnigma/comps/SidePanelTabs/sharedComps";
|
||||
import { usePosthogFeatureFlag } from "~/hooks/usePosthogFeatureFlag";
|
||||
import { isAnyStatusFetching } from "../../utilities";
|
||||
import {
|
||||
useUserObjects,
|
||||
useFeaturedObjects,
|
||||
useSearchFeaturedObjects,
|
||||
useSearchUserdObjects,
|
||||
useFeatureFlags,
|
||||
} from "../../hooks";
|
||||
|
||||
const filterEngineCategories = [FilterEngineCategories.EXPRESSION];
|
||||
|
||||
export const ExpressionTab = () => {
|
||||
const showSearchObjectComponent = usePosthogFeatureFlag(
|
||||
FeatureFlags.SHOW_SEARCH_OBJECTS,
|
||||
);
|
||||
const { showSearchObjectComponent, showUploadButton } = useFeatureFlags();
|
||||
|
||||
const showUploadButton = usePosthogFeatureFlag(FeatureFlags.DEV_ONLY);
|
||||
|
||||
const [openUploadModal, setOpenUploadModal] = useState(false);
|
||||
|
||||
|
||||
+32
-17
@@ -1,6 +1,8 @@
|
||||
import { useEffect } from "react";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { LinksFunction } from "@remix-run/deno";
|
||||
import { posthog } from "posthog-js";
|
||||
import { PostHogProvider } from "posthog-js/react";
|
||||
import {
|
||||
Links,
|
||||
Meta,
|
||||
@@ -99,7 +101,9 @@ export default function App() {
|
||||
<body className="overflow-hidden bg-ui-background">
|
||||
{data && <GlobalSettingsManager env={data.ENV} />}
|
||||
<div className="topbar-spacer" />
|
||||
<Outlet />
|
||||
<PostHogProvider client={posthog}>
|
||||
<Outlet />
|
||||
</PostHogProvider>
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
</body>
|
||||
@@ -109,33 +113,44 @@ export default function App() {
|
||||
|
||||
const GlobalSettingsManager = ({ env }: { env: Record<string, string> }) => {
|
||||
useSignals();
|
||||
useEffect(() => {
|
||||
function setPage() {
|
||||
// TODO address this issue with zooming
|
||||
pageHeight.value = window.innerHeight;
|
||||
pageWidth.value = window.innerWidth;
|
||||
}
|
||||
|
||||
setPage();
|
||||
|
||||
window.addEventListener("resize", setPage);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", setPage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
/// Initizations that depends on ENV vars ///
|
||||
function PostHogInit() {
|
||||
const data = EnvironmentVariables.values;
|
||||
const apiKey = data.REACT_APP_PUBLIC_POSTHOG_KEY as string;
|
||||
posthog.init(apiKey, {
|
||||
//HACK: This is the default host from Netlify, but need to figure out why it isn't working on prod.
|
||||
// api_host: data.DEPLOY_PRIME_URL + "/ingest" as string,
|
||||
api_host: "https://studio.storyteller.ai/ingest" as string,
|
||||
ui_host: data.REACT_APP_PUBLIC_POSTHOG_UI as string,
|
||||
});
|
||||
}
|
||||
useEffect(() => {
|
||||
EnvironmentVariables.initialize(env);
|
||||
PostHogInit();
|
||||
}, [env]);
|
||||
|
||||
useEffect(() => {
|
||||
/// Initizations that run only once on 1ST mount ///
|
||||
function setPage() {
|
||||
// TODO address this issue with zooming
|
||||
pageHeight.value = window.innerHeight;
|
||||
pageWidth.value = window.innerWidth;
|
||||
}
|
||||
function initWizard() {
|
||||
if (showWizard.value) {
|
||||
return;
|
||||
}
|
||||
const wizard = localStorage.getItem("storyteller-wizard");
|
||||
showWizard.value = wizard ? "" : "initial";
|
||||
localStorage.setItem("storyteller-wizard", "shown");
|
||||
}
|
||||
useEffect(() => {
|
||||
initWizard();
|
||||
setPage();
|
||||
window.addEventListener("resize", setPage);
|
||||
return () => {
|
||||
window.removeEventListener("resize", setPage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
import { computed, signal } from "@preact/signals-core";
|
||||
import { ActiveSubscriptions, UserInfo } from "~/models";
|
||||
import { AUTH_STATUS, LoyaltyProgram } from "~/enums";
|
||||
import { AUTH_STATUS, LoyaltyProgram, USER_FEATURE_FLAGS } from "~/enums";
|
||||
|
||||
const status = signal<AUTH_STATUS>(AUTH_STATUS.INIT);
|
||||
const userInfo = signal<UserInfo | undefined>(undefined);
|
||||
const activeSubs = signal<ActiveSubscriptions | undefined>(undefined);
|
||||
|
||||
const canUpload3D = computed(() => {
|
||||
if (!userInfo.value || !userInfo.value.maybe_feature_flags) {
|
||||
return undefined;
|
||||
}
|
||||
return userInfo.value.maybe_feature_flags.includes(
|
||||
USER_FEATURE_FLAGS.UPLOAD_3D,
|
||||
);
|
||||
});
|
||||
|
||||
const hasAccess = computed(() => {
|
||||
if (
|
||||
userInfo.value === undefined ||
|
||||
@@ -33,6 +42,7 @@ export const authentication = {
|
||||
status,
|
||||
userInfo,
|
||||
activeSubs,
|
||||
canUpload3D,
|
||||
hasAccess,
|
||||
hasPremium,
|
||||
};
|
||||
@@ -1,8 +1,6 @@
|
||||
import { authentication } from "~/signals";
|
||||
|
||||
import { AUTH_STATUS } from "~/enums";
|
||||
import { UserInfo, ActiveSubscriptions } from "~/models";
|
||||
import { flushAllBackgroundLoadedMedia } from "~/signals";
|
||||
import { authentication, flushAllBackgroundLoadedMedia } from "~/signals";
|
||||
|
||||
export const updateAuthStatus = (newStatus: AUTH_STATUS) => {
|
||||
authentication.status.value = newStatus;
|
||||
|
||||
Reference in new issue
Block a user