lock image generation

This commit is contained in:
bflatastic committed 2024-05-03 12:07:12 +07:00
1 parent bf63bc2b6b
commit e94da0ef4d
3 files changed
+263 -224

No files matched your search

@@ -9,6 +9,7 @@
.overlay {
position: absolute;
z-index: 5;
top: 0;
left: 0;
width: 100%;
@@ -20,7 +21,6 @@
color: rgba($white, 0.8);
font-size: 16px;
pointer-events: all;
text-shadow: 0 0 10px rgba(0, 0, 0, 1);
border: 1px solid rgba($primary, 0.4);
border-radius: 0.5rem;
}
@@ -1,25 +1,31 @@
import { Panel } from "components/common";
import { Button, Panel } from "components/common";
import { Link } from "react-router-dom";
import React from "react";
import "./PremiumLock.scss";
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faLock } from "@fortawesome/pro-solid-svg-icons";
import { faLock, faUp } from "@fortawesome/pro-solid-svg-icons";
interface PremiumLockProps {
requiredPlan?: "plus" | "pro" | "elite";
requiredPlan?: "any" | "plus" | "pro" | "elite";
large?: boolean;
children: React.ReactNode;
session?: any;
sessionSubscriptionsWrapper: SessionSubscriptionsWrapper;
showCtaButton?: boolean;
}
export default function PremiumLock({
requiredPlan = "plus",
children,
sessionSubscriptionsWrapper,
showCtaButton = false,
large = false,
}: PremiumLockProps) {
const hasAccess = () => {
switch (requiredPlan) {
case "any":
return sessionSubscriptionsWrapper.hasPaidFeatures();
case "plus":
return (
sessionSubscriptionsWrapper.hasActivePlusSubscription() ||
@@ -34,7 +40,7 @@ export default function PremiumLock({
case "elite":
return sessionSubscriptionsWrapper.hasActiveEliteSubscription();
default:
return false;
return sessionSubscriptionsWrapper.hasPaidFeatures();
}
};
@@ -47,11 +53,33 @@ export default function PremiumLock({
{children}
<div className="overlay">
<div className="d-flex flex-column align-items-center gap-2 text-center">
<FontAwesomeIcon icon={faLock} className="me-2 fs-5" />
<div>
This feature requires a{" "}
<Link to="/pricing">{requiredPlan} subscription</Link>
</div>
<FontAwesomeIcon
icon={faLock}
className={`me-2 ${large ? "fs-4" : "fs-5"}`}
/>
{requiredPlan === "any" ? (
<span className="lead fw-medium">
This feature requires a{" "}
<Link to="/pricing" className="lead fw-medium">
subscription plan.
</Link>
</span>
) : (
<span>
This feature requires a{" "}
<Link to="/pricing">{requiredPlan} subscription</Link>
</span>
)}
{showCtaButton && (
<Button
variant="primary"
label="Upgrade your account"
icon={faUp}
to="/pricing"
className="mt-2"
/>
)}
</div>
</div>
</Panel>
@@ -259,6 +259,10 @@ function SdInferencePanel({
return false;
}
if (!sessionSubscriptionsWrapper.hasPaidFeatures()) {
return false;
}
if (!sessionSubscriptionsWrapper.hasActiveProSubscription()) {
batchCountSet(1);
}
@@ -310,234 +314,241 @@ function SdInferencePanel({
};
return (
<div>
<SplitPanel dividerHeader={true}>
<SplitPanel.Header padding={true}>
<h4 className="fw-semibold mb-0 flex-grow-1">Generate an Image</h4>
</SplitPanel.Header>
<PremiumLock
sessionSubscriptionsWrapper={sessionSubscriptionsWrapper}
requiredPlan="any"
showCtaButton={true}
large={true}
>
<div>
<SplitPanel dividerHeader={true}>
<SplitPanel.Header padding={true}>
<h4 className="fw-semibold mb-0 flex-grow-1">Generate an Image</h4>
</SplitPanel.Header>
<SplitPanel.Body padding={true}>
<div className="d-flex flex-column gap-3 mb-4">
{(isStandalone || weightPageType === "lora") && (
<SelectModal
required={true}
modalTitle="Select Stable Diffusion Weight"
label="Select a Stable Diffusion Weight"
onSelect={handleOnWeightSelect}
tabs={[
{
label: "All Weights",
tabKey: "allWeights",
typeFilter: "sd_1.5",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedWeights",
typeFilter: "sd_1.5",
searcher: false,
type: "weights",
onlyBookmarked: true,
},
]}
<SplitPanel.Body padding={true}>
<div className="d-flex flex-column gap-3 mb-4">
{(isStandalone || weightPageType === "lora") && (
<SelectModal
required={true}
modalTitle="Select Stable Diffusion Weight"
label="Select a Stable Diffusion Weight"
onSelect={handleOnWeightSelect}
tabs={[
{
label: "All Weights",
tabKey: "allWeights",
typeFilter: "sd_1.5",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedWeights",
typeFilter: "sd_1.5",
searcher: false,
type: "weights",
onlyBookmarked: true,
},
]}
/>
)}
<TempTextArea
{...{
label: "Prompt",
placeholder: "Enter a prompt",
onChange: handlePromptChange,
value: prompt,
required: true,
}}
/>
)}
<TempTextArea
{...{
label: "Prompt",
placeholder: "Enter a prompt",
onChange: handlePromptChange,
value: prompt,
required: true,
}}
/>
<TempTextArea
{...{
label: "Negative Prompt",
name: "negativePrompt",
placeholder: "Enter a negative prompt",
onChange: handleNegativePromptChange,
value: negativePrompt,
}}
/>
<SegmentButtons
{...{
label: "Aspect Ratio",
name: "aspectRatio",
onChange,
options: dimensionOpts,
value: aspectRatio,
}}
/>
<div>
<Label label="Number of Generations" />
<PremiumLock
sessionSubscriptionsWrapper={sessionSubscriptionsWrapper}
requiredPlan="pro"
>
<SegmentButtons
{...{
name: "batchCount",
onChange,
options: batchCountOpts,
value: batchCount,
}}
/>
</PremiumLock>
</div>
</div>
<Accordion>
<Accordion.Item title="Advanced">
<div className="p-3 d-flex flex-column gap-3">
<TempSelect
{...{
label: "Sampler",
name: "sampler",
onChange,
options: samplerOpts,
value: sampler,
}}
/>
<div>
<label className="sub-title">Seed</label>
<div className="d-flex gap-2 align-items-center">
<SegmentButtons
{...{
name: "seed",
onChange: handleSeedChange,
options: seedOpts,
value: seed,
}}
/>
<Input
placeholder="Random"
value={seedNumber}
onChange={handleSeedNumberChange}
type="number"
onBlur={handleBlur}
/>
</div>
</div>
<NumberSlider
{...{
min: 1,
max: 30,
name: "cfgScale",
label: "CFG Scale",
onChange,
thumbTip: "CFG Scale",
value: cfgScale,
step: 0.5,
}}
/>
<NumberSlider
{...{
min: 8,
max: 64,
name: "samples",
label: "Samples",
onChange,
thumbTip: "Samples",
value: samples,
}}
/>
{weightPageType === "sd" && (
<SelectModal
modalTitle="Select LoRA Weight"
label="Additional LoRA Weight"
onSelect={handleOnSelect}
tabs={[
{
label: "All LoRA Weights",
tabKey: "allLoraWeights",
typeFilter: "loRA",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedLoraWeights",
typeFilter: "loRA",
searcher: false,
type: "weights",
onlyBookmarked: true,
},
]}
<TempTextArea
{...{
label: "Negative Prompt",
name: "negativePrompt",
placeholder: "Enter a negative prompt",
onChange: handleNegativePromptChange,
value: negativePrompt,
}}
/>
<SegmentButtons
{...{
label: "Aspect Ratio",
name: "aspectRatio",
onChange,
options: dimensionOpts,
value: aspectRatio,
}}
/>
<div>
<Label label="Number of Generations" />
<PremiumLock
sessionSubscriptionsWrapper={sessionSubscriptionsWrapper}
requiredPlan="pro"
>
<SegmentButtons
{...{
name: "batchCount",
onChange,
options: batchCountOpts,
value: batchCount,
}}
/>
)}
</PremiumLock>
</div>
</Accordion.Item>
</Accordion>
<div className="d-flex mt-4 align-items-center flex-wrap gap-4">
{isStandalone && (
<div className="flex-grow-1">
<p className="fs-7">
<span className="opacity-75">
Can't find the model weights you're looking for?
</span>{" "}
<Link to="/upload/sd">Upload your own!</Link>
</p>
</div>
)}
<div className="d-flex gap-2 justify-content-end flex-grow-1">
<Button
{...{
label: "Clear/Reset ",
variant: "secondary",
onClick: resetToInitialState,
}}
/>
<Button
{...{
label: "Generate Image",
disabled: prompt === "" || sdToken === "",
onClick: handleEnqueueImageGen,
isLoading: isEnqueuing,
}}
/>
</div>
</div>
</SplitPanel.Body>
<InferenceJobsList
{...{
failures,
jobType: FrontendInferenceJobType.ImageGeneration,
}}
/>
</SplitPanel>
<Accordion>
<Accordion.Item title="Advanced">
<div className="p-3 d-flex flex-column gap-3">
<TempSelect
{...{
label: "Sampler",
name: "sampler",
onChange,
options: samplerOpts,
value: sampler,
}}
/>
<div>
<label className="sub-title">Seed</label>
<div className="d-flex gap-2 align-items-center">
<SegmentButtons
{...{
name: "seed",
onChange: handleSeedChange,
options: seedOpts,
value: seed,
}}
/>
<Input
placeholder="Random"
value={seedNumber}
onChange={handleSeedNumberChange}
type="number"
onBlur={handleBlur}
/>
</div>
</div>
<NumberSlider
{...{
min: 1,
max: 30,
name: "cfgScale",
label: "CFG Scale",
onChange,
thumbTip: "CFG Scale",
value: cfgScale,
step: 0.5,
}}
/>
<NumberSlider
{...{
min: 8,
max: 64,
name: "samples",
label: "Samples",
onChange,
thumbTip: "Samples",
value: samples,
}}
/>
{weightPageType === "sd" && (
<SelectModal
modalTitle="Select LoRA Weight"
label="Additional LoRA Weight"
onSelect={handleOnSelect}
tabs={[
{
label: "All LoRA Weights",
tabKey: "allLoraWeights",
typeFilter: "loRA",
searcher: true,
type: "weights",
},
{
label: "Bookmarked",
tabKey: "bookmarkedLoraWeights",
typeFilter: "loRA",
searcher: false,
type: "weights",
onlyBookmarked: true,
},
]}
/>
)}
</div>
</Accordion.Item>
</Accordion>
<div className="d-flex mt-4 align-items-center flex-wrap gap-4">
{isStandalone && (
<div className="flex-grow-1">
<p className="fs-7">
<span className="opacity-75">
Can't find the model weights you're looking for?
</span>{" "}
<Link to="/upload/sd">Upload your own!</Link>
</p>
</div>
)}
<div className="d-flex gap-2 justify-content-end flex-grow-1">
<Button
{...{
label: "Clear/Reset ",
variant: "secondary",
onClick: resetToInitialState,
}}
/>
<Button
{...{
label: "Generate Image",
disabled: prompt === "" || sdToken === "",
onClick: handleEnqueueImageGen,
isLoading: isEnqueuing,
}}
/>
</div>
</div>
</SplitPanel.Body>
{inferenceJobs[0] ? (
<div className={isStandalone ? "mt-4" : "mt-3"}>
<InferenceJobsList
{...{
failures,
value: 0,
jobType: FrontendInferenceJobType.ImageGeneration,
}}
/>
</div>
) : (
<>
{isStandalone && (
<Panel padding={true} className="mt-4">
<div className="d-flex flex-column align-items-center justify-content-center gap-2 py-5 opacity-75">
<h4 className="fw-semibold mb-0">
<FontAwesomeIcon icon={faList} className="me-2 fs-5" />
No jobs queued
</h4>
</SplitPanel>
<p>Your queued image jobs will appear here.</p>
</div>
</Panel>
)}
</>
)}
</div>
{inferenceJobs[0] ? (
<div className={isStandalone ? "mt-4" : "mt-3"}>
<InferenceJobsList
{...{
failures,
value: 0,
jobType: FrontendInferenceJobType.ImageGeneration,
}}
/>
</div>
) : (
<>
{isStandalone && (
<Panel padding={true} className="mt-4">
<div className="d-flex flex-column align-items-center justify-content-center gap-2 py-5 opacity-75">
<h4 className="fw-semibold mb-0">
<FontAwesomeIcon icon={faList} className="me-2 fs-5" />
No jobs queued
</h4>
<p>Your queued image jobs will appear here.</p>
</div>
</Panel>
)}
</>
)}
</div>
</PremiumLock>
);
}