@automattic/jetpack-ai-client 0.14.5 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/build/ask-question/sync.d.ts +2 -8
- package/build/ask-question/sync.js +20 -19
- package/build/hooks/use-ai-suggestions/index.d.ts +7 -0
- package/build/hooks/use-ai-suggestions/index.js +17 -3
- package/build/hooks/use-image-generator/index.js +1 -1
- package/build/hooks/use-save-to-media-library/index.d.ts +12 -0
- package/build/hooks/use-save-to-media-library/index.js +74 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +5 -0
- package/build/libs/index.d.ts +1 -1
- package/build/libs/index.js +1 -1
- package/build/libs/markdown/index.d.ts +2 -2
- package/build/libs/markdown/index.js +2 -2
- package/build/libs/markdown/markdown-to-html.d.ts +8 -1
- package/build/libs/markdown/markdown-to-html.js +10 -1
- package/build/logo-generator/assets/icons/ai.d.ts +6 -0
- package/build/logo-generator/assets/icons/ai.js +8 -0
- package/build/logo-generator/assets/icons/check.d.ts +6 -0
- package/build/logo-generator/assets/icons/check.js +8 -0
- package/build/logo-generator/assets/icons/logo.d.ts +6 -0
- package/build/logo-generator/assets/icons/logo.js +8 -0
- package/build/logo-generator/assets/icons/media.d.ts +6 -0
- package/build/logo-generator/assets/icons/media.js +8 -0
- package/build/logo-generator/components/feature-fetch-failure-screen.d.ts +8 -0
- package/build/logo-generator/components/feature-fetch-failure-screen.js +10 -0
- package/build/logo-generator/components/first-load-screen.d.ts +5 -0
- package/build/logo-generator/components/first-load-screen.js +16 -0
- package/build/logo-generator/components/generator-modal.d.ts +7 -0
- package/build/logo-generator/components/generator-modal.js +184 -0
- package/build/logo-generator/components/history-carousel.d.ts +6 -0
- package/build/logo-generator/components/history-carousel.js +36 -0
- package/build/logo-generator/components/image-loader.d.ts +7 -0
- package/build/logo-generator/components/image-loader.js +12 -0
- package/build/logo-generator/components/logo-presenter.d.ts +4 -0
- package/build/logo-generator/components/logo-presenter.js +106 -0
- package/build/logo-generator/components/prompt.d.ts +5 -0
- package/build/logo-generator/components/prompt.js +96 -0
- package/build/logo-generator/components/upgrade-nudge.d.ts +2 -0
- package/build/logo-generator/components/upgrade-nudge.js +30 -0
- package/build/logo-generator/components/upgrade-screen.d.ts +9 -0
- package/build/logo-generator/components/upgrade-screen.js +24 -0
- package/build/logo-generator/components/visit-site-banner.d.ts +10 -0
- package/build/logo-generator/components/visit-site-banner.js +16 -0
- package/build/logo-generator/constants.d.ts +16 -0
- package/build/logo-generator/constants.js +19 -0
- package/build/logo-generator/hooks/use-checkout.d.ts +4 -0
- package/build/logo-generator/hooks/use-checkout.js +26 -0
- package/build/logo-generator/hooks/use-logo-generator.d.ts +46 -0
- package/build/logo-generator/hooks/use-logo-generator.js +286 -0
- package/build/logo-generator/hooks/use-request-errors.d.ts +16 -0
- package/build/logo-generator/hooks/use-request-errors.js +46 -0
- package/build/logo-generator/index.d.ts +1 -0
- package/build/logo-generator/index.js +1 -0
- package/build/logo-generator/lib/logo-storage.d.ts +58 -0
- package/build/logo-generator/lib/logo-storage.js +123 -0
- package/build/logo-generator/lib/media-exists.d.ts +12 -0
- package/build/logo-generator/lib/media-exists.js +33 -0
- package/build/logo-generator/lib/set-site-logo.d.ts +13 -0
- package/build/logo-generator/lib/set-site-logo.js +26 -0
- package/build/logo-generator/lib/wpcom-limited-request.d.ts +7 -0
- package/build/logo-generator/lib/wpcom-limited-request.js +33 -0
- package/build/logo-generator/store/actions.d.ts +105 -0
- package/build/logo-generator/store/actions.js +193 -0
- package/build/logo-generator/store/constants.d.ts +44 -0
- package/build/logo-generator/store/constants.js +44 -0
- package/build/logo-generator/store/index.d.ts +1 -0
- package/build/logo-generator/store/index.js +19 -0
- package/build/logo-generator/store/initial-state.d.ts +3 -0
- package/build/logo-generator/store/initial-state.js +40 -0
- package/build/logo-generator/store/reducer.d.ts +347 -0
- package/build/logo-generator/store/reducer.js +293 -0
- package/build/logo-generator/store/selectors.d.ts +119 -0
- package/build/logo-generator/store/selectors.js +173 -0
- package/build/logo-generator/store/types.d.ts +164 -0
- package/build/logo-generator/store/types.js +1 -0
- package/build/logo-generator/types.d.ts +82 -0
- package/build/logo-generator/types.js +1 -0
- package/build/types.d.ts +6 -0
- package/package.json +5 -3
- package/src/ask-question/sync.ts +22 -27
- package/src/hooks/use-ai-suggestions/index.ts +22 -3
- package/src/hooks/use-image-generator/index.ts +1 -1
- package/src/hooks/use-save-to-media-library/index.ts +95 -0
- package/src/index.ts +6 -0
- package/src/libs/index.ts +1 -0
- package/src/libs/markdown/index.ts +2 -2
- package/src/libs/markdown/markdown-to-html.ts +20 -3
- package/src/logo-generator/assets/icons/ai.tsx +21 -0
- package/src/logo-generator/assets/icons/check.tsx +23 -0
- package/src/logo-generator/assets/icons/icons.scss +5 -0
- package/src/logo-generator/assets/icons/logo.tsx +23 -0
- package/src/logo-generator/assets/icons/media.tsx +24 -0
- package/src/logo-generator/assets/images/jetpack-logo.svg +4 -0
- package/src/logo-generator/assets/images/loader.gif +0 -0
- package/src/logo-generator/assets/index.d.ts +3 -0
- package/src/logo-generator/components/feature-fetch-failure-screen.tsx +35 -0
- package/src/logo-generator/components/first-load-screen.scss +12 -0
- package/src/logo-generator/components/first-load-screen.tsx +32 -0
- package/src/logo-generator/components/generator-modal.scss +92 -0
- package/src/logo-generator/components/generator-modal.tsx +291 -0
- package/src/logo-generator/components/history-carousel.scss +36 -0
- package/src/logo-generator/components/history-carousel.tsx +57 -0
- package/src/logo-generator/components/image-loader.tsx +22 -0
- package/src/logo-generator/components/logo-presenter.scss +116 -0
- package/src/logo-generator/components/logo-presenter.tsx +234 -0
- package/src/logo-generator/components/prompt.scss +102 -0
- package/src/logo-generator/components/prompt.tsx +211 -0
- package/src/logo-generator/components/upgrade-nudge.scss +43 -0
- package/src/logo-generator/components/upgrade-nudge.tsx +58 -0
- package/src/logo-generator/components/upgrade-screen.tsx +67 -0
- package/src/logo-generator/components/visit-site-banner.scss +29 -0
- package/src/logo-generator/components/visit-site-banner.tsx +50 -0
- package/src/logo-generator/constants.ts +22 -0
- package/src/logo-generator/hooks/use-checkout.ts +37 -0
- package/src/logo-generator/hooks/use-logo-generator.ts +389 -0
- package/src/logo-generator/hooks/use-request-errors.ts +70 -0
- package/src/logo-generator/index.ts +1 -0
- package/src/logo-generator/lib/logo-storage.ts +166 -0
- package/src/logo-generator/lib/media-exists.ts +42 -0
- package/src/logo-generator/lib/set-site-logo.ts +32 -0
- package/src/logo-generator/lib/wpcom-limited-request.ts +41 -0
- package/src/logo-generator/store/actions.ts +251 -0
- package/src/logo-generator/store/constants.ts +49 -0
- package/src/logo-generator/store/index.ts +25 -0
- package/src/logo-generator/store/initial-state.ts +43 -0
- package/src/logo-generator/store/reducer.ts +387 -0
- package/src/logo-generator/store/selectors.ts +201 -0
- package/src/logo-generator/store/types.ts +207 -0
- package/src/logo-generator/types.ts +97 -0
- package/src/types.ts +8 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
+
import { Modal, Button } from '@wordpress/components';
|
|
7
|
+
import { useDispatch } from '@wordpress/data';
|
|
8
|
+
import { __ } from '@wordpress/i18n';
|
|
9
|
+
import { external, Icon } from '@wordpress/icons';
|
|
10
|
+
import clsx from 'clsx';
|
|
11
|
+
import debugFactory from 'debug';
|
|
12
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
13
|
+
/**
|
|
14
|
+
* Internal dependencies
|
|
15
|
+
*/
|
|
16
|
+
import { DEFAULT_LOGO_COST, EVENT_MODAL_OPEN, EVENT_FEEDBACK, EVENT_MODAL_CLOSE, EVENT_PLACEMENT_QUICK_LINKS, EVENT_GENERATE, } from '../constants.js';
|
|
17
|
+
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
18
|
+
import useRequestErrors from '../hooks/use-request-errors.js';
|
|
19
|
+
import { isLogoHistoryEmpty, clearDeletedMedia } from '../lib/logo-storage.js';
|
|
20
|
+
import { STORE_NAME } from '../store/index.js';
|
|
21
|
+
import { FeatureFetchFailureScreen } from './feature-fetch-failure-screen.js';
|
|
22
|
+
import { FirstLoadScreen } from './first-load-screen.js';
|
|
23
|
+
import { HistoryCarousel } from './history-carousel.js';
|
|
24
|
+
import { LogoPresenter } from './logo-presenter.js';
|
|
25
|
+
import { Prompt } from './prompt.js';
|
|
26
|
+
import { UpgradeScreen } from './upgrade-screen.js';
|
|
27
|
+
import { VisitSiteBanner } from './visit-site-banner.js';
|
|
28
|
+
import './generator-modal.scss';
|
|
29
|
+
const debug = debugFactory('jetpack-ai-calypso:generator-modal');
|
|
30
|
+
export const GeneratorModal = ({ isOpen, onClose, siteDetails, context, }) => {
|
|
31
|
+
const { tracks } = useAnalytics();
|
|
32
|
+
const { recordEvent: recordTracksEvent } = tracks;
|
|
33
|
+
const { setSiteDetails, fetchAiAssistantFeature, loadLogoHistory } = useDispatch(STORE_NAME);
|
|
34
|
+
const [loadingState, setLoadingState] = useState(null);
|
|
35
|
+
const [initialPrompt, setInitialPrompt] = useState();
|
|
36
|
+
const needsToHandleModalOpen = useRef(true);
|
|
37
|
+
const requestedFeatureData = useRef(false);
|
|
38
|
+
const [needsFeature, setNeedsFeature] = useState(false);
|
|
39
|
+
const [needsMoreRequests, setNeedsMoreRequests] = useState(false);
|
|
40
|
+
const [upgradeURL, setUpgradeURL] = useState('');
|
|
41
|
+
const { selectedLogo, getAiAssistantFeature, generateFirstPrompt, generateLogo, setContext } = useLogoGenerator();
|
|
42
|
+
const { featureFetchError, firstLogoPromptFetchError, clearErrors } = useRequestErrors();
|
|
43
|
+
const siteId = siteDetails?.ID;
|
|
44
|
+
const siteURL = siteDetails?.URL;
|
|
45
|
+
const [logoAccepted, setLogoAccepted] = useState(false);
|
|
46
|
+
// First fetch the feature data so we have the most up-to-date info from the backend.
|
|
47
|
+
const feature = getAiAssistantFeature();
|
|
48
|
+
const generateFirstLogo = useCallback(async () => {
|
|
49
|
+
try {
|
|
50
|
+
// First generate the prompt based on the site's data.
|
|
51
|
+
setLoadingState('analyzing');
|
|
52
|
+
recordTracksEvent(EVENT_GENERATE, { context, tool: 'first-prompt' });
|
|
53
|
+
const prompt = await generateFirstPrompt();
|
|
54
|
+
setInitialPrompt(prompt);
|
|
55
|
+
// Then generate the logo based on the prompt.
|
|
56
|
+
setLoadingState('generating');
|
|
57
|
+
await generateLogo({ prompt });
|
|
58
|
+
setLoadingState(null);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
debug('Error generating first logo', error);
|
|
62
|
+
setLoadingState(null);
|
|
63
|
+
}
|
|
64
|
+
}, [context, generateFirstPrompt, generateLogo]);
|
|
65
|
+
/*
|
|
66
|
+
* Called ONCE to check the feature data to make sure the site is allowed to do the generation.
|
|
67
|
+
* Also, checks site history and trigger a new generation in case there are no logos to present.
|
|
68
|
+
*/
|
|
69
|
+
const initializeModal = useCallback(async () => {
|
|
70
|
+
try {
|
|
71
|
+
const hasHistory = !isLogoHistoryEmpty(String(siteId));
|
|
72
|
+
const logoCost = feature?.costs?.['jetpack-ai-logo-generator']?.logo ?? DEFAULT_LOGO_COST;
|
|
73
|
+
const promptCreationCost = 1;
|
|
74
|
+
const currentLimit = feature?.currentTier?.value || 0;
|
|
75
|
+
const currentUsage = feature?.usagePeriod?.requestsCount || 0;
|
|
76
|
+
const isUnlimited = currentLimit === 1;
|
|
77
|
+
const hasNoNextTier = !feature?.nextTier; // If there is no next tier, the user cannot upgrade.
|
|
78
|
+
// The user needs an upgrade immediately if they have no logos and not enough requests remaining for one prompt and one logo generation.
|
|
79
|
+
const siteNeedsMoreRequests = !isUnlimited &&
|
|
80
|
+
!hasNoNextTier &&
|
|
81
|
+
!hasHistory &&
|
|
82
|
+
currentLimit - currentUsage < logoCost + promptCreationCost;
|
|
83
|
+
// If the site requires an upgrade, set the upgrade URL and show the upgrade screen immediately.
|
|
84
|
+
setNeedsFeature(!feature?.hasFeature ?? true);
|
|
85
|
+
setNeedsMoreRequests(siteNeedsMoreRequests);
|
|
86
|
+
if (!feature?.hasFeature || siteNeedsMoreRequests) {
|
|
87
|
+
const siteUpgradeURL = new URL(`${location.origin}/checkout/${siteDetails?.domain}/${feature?.nextTier?.slug}`);
|
|
88
|
+
siteUpgradeURL.searchParams.set('redirect_to', location.href);
|
|
89
|
+
setUpgradeURL(siteUpgradeURL.toString());
|
|
90
|
+
setLoadingState(null);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Load the logo history and clear any deleted media.
|
|
94
|
+
await clearDeletedMedia(String(siteId));
|
|
95
|
+
loadLogoHistory(siteId);
|
|
96
|
+
// If there is any logo, we do not need to generate a first logo again.
|
|
97
|
+
if (!isLogoHistoryEmpty(String(siteId))) {
|
|
98
|
+
setLoadingState(null);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// If the site does not require an upgrade and has no logos stored, generate the first prompt based on the site's data.
|
|
102
|
+
generateFirstLogo();
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
debug('Error fetching feature', error);
|
|
106
|
+
setLoadingState(null);
|
|
107
|
+
}
|
|
108
|
+
}, [
|
|
109
|
+
feature,
|
|
110
|
+
generateFirstLogo,
|
|
111
|
+
loadLogoHistory,
|
|
112
|
+
clearDeletedMedia,
|
|
113
|
+
isLogoHistoryEmpty,
|
|
114
|
+
siteId,
|
|
115
|
+
]);
|
|
116
|
+
const handleModalOpen = useCallback(async () => {
|
|
117
|
+
setContext(context);
|
|
118
|
+
recordTracksEvent(EVENT_MODAL_OPEN, { context, placement: EVENT_PLACEMENT_QUICK_LINKS });
|
|
119
|
+
initializeModal();
|
|
120
|
+
}, [setContext, context, initializeModal]);
|
|
121
|
+
const closeModal = () => {
|
|
122
|
+
// Reset the state when the modal is closed, so we trigger the modal initialization again when it's opened.
|
|
123
|
+
needsToHandleModalOpen.current = true;
|
|
124
|
+
onClose();
|
|
125
|
+
setLoadingState(null);
|
|
126
|
+
setNeedsFeature(false);
|
|
127
|
+
setNeedsMoreRequests(false);
|
|
128
|
+
clearErrors();
|
|
129
|
+
setLogoAccepted(false);
|
|
130
|
+
recordTracksEvent(EVENT_MODAL_CLOSE, { context, placement: EVENT_PLACEMENT_QUICK_LINKS });
|
|
131
|
+
};
|
|
132
|
+
const handleApplyLogo = () => {
|
|
133
|
+
setLogoAccepted(true);
|
|
134
|
+
};
|
|
135
|
+
const handleCloseAndReload = () => {
|
|
136
|
+
closeModal();
|
|
137
|
+
setTimeout(() => {
|
|
138
|
+
// Reload the page to update the logo.
|
|
139
|
+
window.location.reload();
|
|
140
|
+
}, 1000);
|
|
141
|
+
};
|
|
142
|
+
const handleFeedbackClick = () => {
|
|
143
|
+
recordTracksEvent(EVENT_FEEDBACK, { context });
|
|
144
|
+
};
|
|
145
|
+
// Set site details when siteId changes
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (siteId) {
|
|
148
|
+
setSiteDetails(siteDetails);
|
|
149
|
+
}
|
|
150
|
+
// When the site details are set, we need to fetch the feature data.
|
|
151
|
+
if (!requestedFeatureData.current) {
|
|
152
|
+
requestedFeatureData.current = true;
|
|
153
|
+
fetchAiAssistantFeature();
|
|
154
|
+
}
|
|
155
|
+
}, [siteId, siteDetails, setSiteDetails]);
|
|
156
|
+
// Handles modal opening logic
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
// While the modal is not open, the siteId is not set, or the feature data is not available, do nothing.
|
|
159
|
+
if (!isOpen || !siteId || !feature?.costs) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Prevent multiple calls of the handleModalOpen function
|
|
163
|
+
if (needsToHandleModalOpen.current) {
|
|
164
|
+
needsToHandleModalOpen.current = false;
|
|
165
|
+
handleModalOpen();
|
|
166
|
+
}
|
|
167
|
+
}, [isOpen, siteId, handleModalOpen, feature]);
|
|
168
|
+
let body;
|
|
169
|
+
if (loadingState) {
|
|
170
|
+
body = _jsx(FirstLoadScreen, { state: loadingState });
|
|
171
|
+
}
|
|
172
|
+
else if (featureFetchError || firstLogoPromptFetchError) {
|
|
173
|
+
body = _jsx(FeatureFetchFailureScreen, { onCancel: closeModal, onRetry: initializeModal });
|
|
174
|
+
}
|
|
175
|
+
else if (needsFeature || needsMoreRequests) {
|
|
176
|
+
body = (_jsx(UpgradeScreen, { onCancel: closeModal, upgradeURL: upgradeURL, reason: needsFeature ? 'feature' : 'requests' }));
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
body = (_jsxs(_Fragment, { children: [!logoAccepted && _jsx(Prompt, { initialPrompt: initialPrompt }), _jsx(LogoPresenter, { logo: selectedLogo, onApplyLogo: handleApplyLogo, logoAccepted: logoAccepted, siteId: String(siteId) }), logoAccepted ? (_jsxs("div", { className: "jetpack-ai-logo-generator__accept", children: [_jsx(VisitSiteBanner, { siteURL: siteURL, onVisitBlankTarget: handleCloseAndReload }), _jsxs("div", { className: "jetpack-ai-logo-generator__accept-actions", children: [_jsx(Button, { variant: "link", onClick: handleCloseAndReload, children: __('Close and refresh', 'jetpack-ai-client') }), _jsx(Button, { href: siteURL, variant: "primary", children: __('Visit site', 'jetpack-ai-client') })] })] })) : (_jsxs(_Fragment, { children: [_jsx(HistoryCarousel, {}), _jsx("div", { className: "jetpack-ai-logo-generator__footer", children: _jsxs(Button, { variant: "link", className: "jetpack-ai-logo-generator__feedback-button", href: "https://jetpack.com/redirect/?source=jetpack-ai-feedback", target: "_blank", onClick: handleFeedbackClick, children: [_jsx("span", { children: __('Provide feedback', 'jetpack-ai-client') }), _jsx(Icon, { icon: external, className: "icon" })] }) })] }))] }));
|
|
180
|
+
}
|
|
181
|
+
return (_jsx(_Fragment, { children: isOpen && (_jsx(Modal, { className: "jetpack-ai-logo-generator-modal", onRequestClose: logoAccepted ? handleCloseAndReload : closeModal, shouldCloseOnClickOutside: false, shouldCloseOnEsc: false, title: __('Jetpack AI Logo Generator', 'jetpack-ai-client'), children: _jsx("div", { className: clsx('jetpack-ai-logo-generator-modal__body', {
|
|
182
|
+
'notice-modal': needsFeature || needsMoreRequests || featureFetchError || firstLogoPromptFetchError,
|
|
183
|
+
}), children: body }) })) }));
|
|
184
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
+
import { Button } from '@wordpress/components';
|
|
7
|
+
import clsx from 'clsx';
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import { EVENT_NAVIGATE } from '../constants.js';
|
|
12
|
+
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
13
|
+
import './history-carousel.scss';
|
|
14
|
+
export const HistoryCarousel = () => {
|
|
15
|
+
const { tracks } = useAnalytics();
|
|
16
|
+
const { recordEvent: recordTracksEvent } = tracks;
|
|
17
|
+
const { logos, selectedLogo, setSelectedLogoIndex, context } = useLogoGenerator();
|
|
18
|
+
const handleClick = (index) => {
|
|
19
|
+
recordTracksEvent(EVENT_NAVIGATE, {
|
|
20
|
+
context,
|
|
21
|
+
logos_count: logos.length,
|
|
22
|
+
selected_logo: index + 1,
|
|
23
|
+
});
|
|
24
|
+
setSelectedLogoIndex(index);
|
|
25
|
+
};
|
|
26
|
+
const thumbnailFrom = (url) => {
|
|
27
|
+
const thumbnailURL = new URL(url);
|
|
28
|
+
if (!thumbnailURL.searchParams.has('resize')) {
|
|
29
|
+
thumbnailURL.searchParams.append('resize', '48,48');
|
|
30
|
+
}
|
|
31
|
+
return thumbnailURL.toString();
|
|
32
|
+
};
|
|
33
|
+
return (_jsx("div", { className: "jetpack-ai-logo-generator__carousel", children: logos.map((logo, index) => (_jsx(Button, { className: clsx('jetpack-ai-logo-generator__carousel-logo', {
|
|
34
|
+
'is-selected': logo.url === selectedLogo.url,
|
|
35
|
+
}), onClick: () => handleClick(index), children: _jsx("img", { src: thumbnailFrom(logo.url), alt: logo.description }) }, logo.url))) }));
|
|
36
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import clsx from 'clsx';
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import loader from '../assets/images/loader.gif';
|
|
10
|
+
export const ImageLoader = ({ className = null }) => {
|
|
11
|
+
return (_jsx("img", { src: loader, alt: "Loading", className: clsx('jetpack-ai-logo-generator-modal__loader', className) }));
|
|
12
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
+
import { Button, Icon } from '@wordpress/components';
|
|
7
|
+
import { useDispatch } from '@wordpress/data';
|
|
8
|
+
import { __ } from '@wordpress/i18n';
|
|
9
|
+
import debugFactory from 'debug';
|
|
10
|
+
/**
|
|
11
|
+
* Internal dependencies
|
|
12
|
+
*/
|
|
13
|
+
import CheckIcon from '../assets/icons/check.js';
|
|
14
|
+
import LogoIcon from '../assets/icons/logo.js';
|
|
15
|
+
import MediaIcon from '../assets/icons/media.js';
|
|
16
|
+
import { EVENT_SAVE, EVENT_USE } from '../constants.js';
|
|
17
|
+
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
18
|
+
import useRequestErrors from '../hooks/use-request-errors.js';
|
|
19
|
+
import { updateLogo } from '../lib/logo-storage.js';
|
|
20
|
+
import { STORE_NAME } from '../store/index.js';
|
|
21
|
+
import { ImageLoader } from './image-loader.js';
|
|
22
|
+
import './logo-presenter.scss';
|
|
23
|
+
const debug = debugFactory('jetpack-ai-calypso:logo-presenter');
|
|
24
|
+
const SaveInLibraryButton = ({ siteId }) => {
|
|
25
|
+
const { tracks } = useAnalytics();
|
|
26
|
+
const { recordEvent: recordTracksEvent } = tracks;
|
|
27
|
+
const { saveLogo, selectedLogo, isSavingLogoToLibrary: saving, logos, selectedLogoIndex, context, } = useLogoGenerator();
|
|
28
|
+
const saved = !!selectedLogo?.mediaId;
|
|
29
|
+
const { loadLogoHistory } = useDispatch(STORE_NAME);
|
|
30
|
+
const handleClick = async () => {
|
|
31
|
+
if (!saved && !saving) {
|
|
32
|
+
recordTracksEvent(EVENT_SAVE, {
|
|
33
|
+
context,
|
|
34
|
+
logos_count: logos.length,
|
|
35
|
+
selected_logo: selectedLogoIndex ? selectedLogoIndex + 1 : 0,
|
|
36
|
+
});
|
|
37
|
+
try {
|
|
38
|
+
const savedLogo = await saveLogo(selectedLogo);
|
|
39
|
+
// Update localStorage
|
|
40
|
+
updateLogo({
|
|
41
|
+
siteId,
|
|
42
|
+
url: selectedLogo.url,
|
|
43
|
+
newUrl: savedLogo.mediaURL,
|
|
44
|
+
mediaId: savedLogo.mediaId,
|
|
45
|
+
});
|
|
46
|
+
// Update state
|
|
47
|
+
loadLogoHistory(siteId);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
debug('Error saving logo', error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const savingLabel = __('Saving…', 'jetpack-ai-client');
|
|
55
|
+
const savedLabel = __('Saved', 'jetpack-ai-client');
|
|
56
|
+
return !saving && !saved ? (_jsxs(Button, { className: "jetpack-ai-logo-generator-modal-presenter__action", onClick: handleClick, children: [_jsx(Icon, { icon: _jsx(MediaIcon, {}) }), _jsx("span", { className: "action-text", children: __('Save in Library', 'jetpack-ai-client') })] })) : (_jsxs("button", { className: "jetpack-ai-logo-generator-modal-presenter__action", children: [_jsx(Icon, { icon: saving ? _jsx(MediaIcon, {}) : _jsx(CheckIcon, {}) }), _jsx("span", { className: "action-text", children: saving ? savingLabel : savedLabel })] }));
|
|
57
|
+
};
|
|
58
|
+
const UseOnSiteButton = ({ onApplyLogo }) => {
|
|
59
|
+
const { tracks } = useAnalytics();
|
|
60
|
+
const { recordEvent: recordTracksEvent } = tracks;
|
|
61
|
+
const { applyLogo, isSavingLogoToLibrary, isApplyingLogo, selectedLogo, logos, selectedLogoIndex, context, } = useLogoGenerator();
|
|
62
|
+
const handleClick = async () => {
|
|
63
|
+
if (!isApplyingLogo && !isSavingLogoToLibrary) {
|
|
64
|
+
recordTracksEvent(EVENT_USE, {
|
|
65
|
+
context,
|
|
66
|
+
logos_count: logos.length,
|
|
67
|
+
selected_logo: selectedLogoIndex != null ? selectedLogoIndex + 1 : 0,
|
|
68
|
+
});
|
|
69
|
+
try {
|
|
70
|
+
await applyLogo();
|
|
71
|
+
onApplyLogo();
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
debug('Error applying logo', error);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
return isApplyingLogo && !isSavingLogoToLibrary ? (_jsxs("button", { className: "jetpack-ai-logo-generator-modal-presenter__action", children: [_jsx(Icon, { icon: _jsx(LogoIcon, {}) }), _jsx("span", { className: "action-text", children: __('Applying logo…', 'jetpack-ai-client') })] })) : (_jsxs(Button, { className: "jetpack-ai-logo-generator-modal-presenter__action", onClick: handleClick, disabled: isSavingLogoToLibrary || !selectedLogo?.mediaId, children: [_jsx(Icon, { icon: _jsx(LogoIcon, {}) }), _jsx("span", { className: "action-text", children: __('Use on Site', 'jetpack-ai-client') })] }));
|
|
79
|
+
};
|
|
80
|
+
const LogoLoading = () => {
|
|
81
|
+
return (_jsxs(_Fragment, { children: [_jsx(ImageLoader, { className: "jetpack-ai-logo-generator-modal-presenter__logo" }), _jsx("span", { className: "jetpack-ai-logo-generator-modal-presenter__loading-text", children: __('Generating new logo…', 'jetpack-ai-client') })] }));
|
|
82
|
+
};
|
|
83
|
+
const LogoReady = ({ siteId, logo, onApplyLogo, }) => {
|
|
84
|
+
return (_jsxs(_Fragment, { children: [_jsx("img", { src: logo.url, alt: logo.description, className: "jetpack-ai-logo-generator-modal-presenter__logo" }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal-presenter__action-wrapper", children: [_jsx("span", { className: "jetpack-ai-logo-generator-modal-presenter__description", children: logo.description }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal-presenter__actions", children: [_jsx(SaveInLibraryButton, { siteId: siteId }), _jsx(UseOnSiteButton, { onApplyLogo: onApplyLogo })] })] })] }));
|
|
85
|
+
};
|
|
86
|
+
const LogoUpdated = ({ logo }) => {
|
|
87
|
+
return (_jsxs(_Fragment, { children: [_jsx("img", { src: logo.url, alt: logo.description, className: "jetpack-ai-logo-generator-modal-presenter__logo" }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal-presenter__success-wrapper", children: [_jsx(Icon, { icon: _jsx(CheckIcon, {}) }), _jsx("span", { children: __('Your logo has been successfully updated!', 'jetpack-ai-client') })] })] }));
|
|
88
|
+
};
|
|
89
|
+
export const LogoPresenter = ({ logo = null, loading = false, onApplyLogo, logoAccepted = false, siteId, }) => {
|
|
90
|
+
const { isRequestingImage } = useLogoGenerator();
|
|
91
|
+
const { saveToLibraryError, logoUpdateError } = useRequestErrors();
|
|
92
|
+
if (!logo) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
let logoContent;
|
|
96
|
+
if (loading || isRequestingImage) {
|
|
97
|
+
logoContent = _jsx(LogoLoading, {});
|
|
98
|
+
}
|
|
99
|
+
else if (logoAccepted) {
|
|
100
|
+
logoContent = _jsx(LogoUpdated, { logo: logo });
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
logoContent = (_jsx(LogoReady, { siteId: String(siteId), logo: logo, onApplyLogo: onApplyLogo }));
|
|
104
|
+
}
|
|
105
|
+
return (_jsxs("div", { className: "jetpack-ai-logo-generator-modal-presenter__wrapper", children: [_jsxs("div", { className: "jetpack-ai-logo-generator-modal-presenter", children: [_jsx("div", { className: "jetpack-ai-logo-generator-modal-presenter__content", children: logoContent }), !logoAccepted && (_jsx("div", { className: "jetpack-ai-logo-generator-modal-presenter__rectangle" }))] }), saveToLibraryError && (_jsx("div", { className: "jetpack-ai-logo-generator__prompt-error", children: __('Error saving the logo to your library. Please try again.', 'jetpack-ai-client') })), logoUpdateError && (_jsx("div", { className: "jetpack-ai-logo-generator__prompt-error", children: __('Error applying the logo to your site. Please try again.', 'jetpack-ai-client') }))] }));
|
|
106
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
+
import { Button, Tooltip } from '@wordpress/components';
|
|
7
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
8
|
+
import { Icon, info } from '@wordpress/icons';
|
|
9
|
+
import debugFactory from 'debug';
|
|
10
|
+
import { useCallback, useEffect, useState, useRef } from 'react';
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies
|
|
13
|
+
*/
|
|
14
|
+
import AiIcon from '../assets/icons/ai.js';
|
|
15
|
+
import { EVENT_GENERATE, MINIMUM_PROMPT_LENGTH, EVENT_UPGRADE, EVENT_PLACEMENT_INPUT_FOOTER, } from '../constants.js';
|
|
16
|
+
import { useCheckout } from '../hooks/use-checkout.js';
|
|
17
|
+
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
18
|
+
import useRequestErrors from '../hooks/use-request-errors.js';
|
|
19
|
+
import { UpgradeNudge } from './upgrade-nudge.js';
|
|
20
|
+
import './prompt.scss';
|
|
21
|
+
const debug = debugFactory('jetpack-ai-calypso:prompt-box');
|
|
22
|
+
export const Prompt = ({ initialPrompt = '' }) => {
|
|
23
|
+
const { tracks } = useAnalytics();
|
|
24
|
+
const { recordEvent: recordTracksEvent } = tracks;
|
|
25
|
+
const [prompt, setPrompt] = useState(initialPrompt);
|
|
26
|
+
const [requestsRemaining, setRequestsRemaining] = useState(0);
|
|
27
|
+
const { enhancePromptFetchError, logoFetchError } = useRequestErrors();
|
|
28
|
+
const { nextTierCheckoutURL: checkoutUrl, hasNextTier } = useCheckout();
|
|
29
|
+
const hasPrompt = prompt?.length >= MINIMUM_PROMPT_LENGTH;
|
|
30
|
+
const { generateLogo, enhancePrompt, setIsEnhancingPrompt, isBusy, isEnhancingPrompt, site, getAiAssistantFeature, requireUpgrade, context, } = useLogoGenerator();
|
|
31
|
+
const enhancingLabel = __('Enhancing…', 'jetpack-ai-client');
|
|
32
|
+
const enhanceLabel = __('Enhance prompt', 'jetpack-ai-client');
|
|
33
|
+
const enhanceButtonLabel = isEnhancingPrompt ? enhancingLabel : enhanceLabel;
|
|
34
|
+
const inputRef = useRef(null);
|
|
35
|
+
const onEnhance = useCallback(async () => {
|
|
36
|
+
debug('Enhancing prompt', prompt);
|
|
37
|
+
setIsEnhancingPrompt(true);
|
|
38
|
+
recordTracksEvent(EVENT_GENERATE, { context, tool: 'enhance-prompt' });
|
|
39
|
+
try {
|
|
40
|
+
const enhancedPrompt = await enhancePrompt({ prompt });
|
|
41
|
+
setPrompt(enhancedPrompt);
|
|
42
|
+
setIsEnhancingPrompt(false);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
debug('Error enhancing prompt', error);
|
|
46
|
+
setIsEnhancingPrompt(false);
|
|
47
|
+
}
|
|
48
|
+
}, [context, enhancePrompt, prompt, setIsEnhancingPrompt]);
|
|
49
|
+
const featureData = getAiAssistantFeature(String(site?.id || ''));
|
|
50
|
+
const currentLimit = featureData?.currentTier?.value || 0;
|
|
51
|
+
const currentUsage = featureData?.usagePeriod?.requestsCount || 0;
|
|
52
|
+
const isUnlimited = currentLimit === 1;
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (currentLimit - currentUsage <= 0) {
|
|
55
|
+
setRequestsRemaining(0);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
setRequestsRemaining(currentLimit - currentUsage);
|
|
59
|
+
}
|
|
60
|
+
}, [currentLimit, currentUsage]);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
// Update prompt text node after enhancement
|
|
63
|
+
if (inputRef.current && inputRef.current.textContent !== prompt) {
|
|
64
|
+
inputRef.current.textContent = prompt;
|
|
65
|
+
}
|
|
66
|
+
}, [prompt]);
|
|
67
|
+
const onGenerate = useCallback(async () => {
|
|
68
|
+
recordTracksEvent(EVENT_GENERATE, { context, tool: 'image' });
|
|
69
|
+
generateLogo({ prompt });
|
|
70
|
+
}, [context, generateLogo, prompt]);
|
|
71
|
+
const onPromptInput = (event) => {
|
|
72
|
+
setPrompt(event.target.textContent || '');
|
|
73
|
+
};
|
|
74
|
+
const onPromptPaste = (event) => {
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
// Paste plain text only
|
|
77
|
+
const text = event.clipboardData.getData('text/plain');
|
|
78
|
+
const selection = window.getSelection();
|
|
79
|
+
if (!selection || !selection.rangeCount) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
selection.deleteFromDocument();
|
|
83
|
+
const range = selection.getRangeAt(0);
|
|
84
|
+
range.insertNode(document.createTextNode(text));
|
|
85
|
+
selection.collapseToEnd();
|
|
86
|
+
setPrompt(inputRef.current?.textContent || '');
|
|
87
|
+
};
|
|
88
|
+
const onUpgradeClick = () => {
|
|
89
|
+
recordTracksEvent(EVENT_UPGRADE, { context, placement: EVENT_PLACEMENT_INPUT_FOOTER });
|
|
90
|
+
};
|
|
91
|
+
return (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt", children: [_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-header", children: [_jsx("div", { className: "jetpack-ai-logo-generator__prompt-label", children: __('Describe your site:', 'jetpack-ai-client') }), _jsx("div", { className: "jetpack-ai-logo-generator__prompt-actions", children: _jsxs(Button, { variant: "link", disabled: isBusy || requireUpgrade || !hasPrompt, onClick: onEnhance, children: [_jsx(AiIcon, {}), _jsx("span", { children: enhanceButtonLabel })] }) })] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-query", children: [_jsx("div", { ref: inputRef, contentEditable: !isBusy && !requireUpgrade,
|
|
92
|
+
// The content editable div is expected to be updated by the enhance prompt, so warnings are suppressed
|
|
93
|
+
suppressContentEditableWarning: true, className: "prompt-query__input", onInput: onPromptInput, onPaste: onPromptPaste, "data-placeholder": __('Describe your site or simply ask for a logo specifying some details about it', 'jetpack-ai-client') }), _jsx(Button, { variant: "primary", className: "jetpack-ai-logo-generator__prompt-submit", onClick: onGenerate, disabled: isBusy || requireUpgrade || !hasPrompt, children: __('Generate', 'jetpack-ai-client') })] }), _jsxs("div", { className: "jetpack-ai-logo-generator__prompt-footer", children: [!isUnlimited && !requireUpgrade && (_jsxs("div", { className: "jetpack-ai-logo-generator__prompt-requests", children: [_jsx("div", { children: sprintf(
|
|
94
|
+
// translators: %u is the number of requests
|
|
95
|
+
__('%u requests remaining.', 'jetpack-ai-client'), requestsRemaining) }), hasNextTier && (_jsxs(_Fragment, { children: ["\u00A0", _jsx(Button, { variant: "link", href: checkoutUrl, target: "_blank", onClick: onUpgradeClick, children: __('Upgrade', 'jetpack-ai-client') })] })), "\u00A0", _jsx(Tooltip, { text: __('Logo generation costs 10 requests; prompt enhancement costs 1 request each', 'jetpack-ai-client'), placement: "bottom", children: _jsx(Icon, { className: "prompt-footer__icon", icon: info }) })] })), !isUnlimited && requireUpgrade && _jsx(UpgradeNudge, {}), enhancePromptFetchError && (_jsx("div", { className: "jetpack-ai-logo-generator__prompt-error", children: __('Error enhancing prompt. Please try again.', 'jetpack-ai-client') })), logoFetchError && (_jsx("div", { className: "jetpack-ai-logo-generator__prompt-error", children: __('Error generating logo. Please try again.', 'jetpack-ai-client') }))] })] }));
|
|
96
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
+
import { Button } from '@wordpress/components';
|
|
7
|
+
import { createInterpolateElement } from '@wordpress/element';
|
|
8
|
+
import { __ } from '@wordpress/i18n';
|
|
9
|
+
import { Icon, warning } from '@wordpress/icons';
|
|
10
|
+
/**
|
|
11
|
+
* Internal dependencies
|
|
12
|
+
*/
|
|
13
|
+
import { EVENT_PLACEMENT_UPGRADE_PROMPT, EVENT_UPGRADE } from '../constants.js';
|
|
14
|
+
import { useCheckout } from '../hooks/use-checkout.js';
|
|
15
|
+
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
16
|
+
import './upgrade-nudge.scss';
|
|
17
|
+
export const UpgradeNudge = () => {
|
|
18
|
+
const { tracks } = useAnalytics();
|
|
19
|
+
const { recordEvent: recordTracksEvent } = tracks;
|
|
20
|
+
const buttonText = __('Upgrade', 'jetpack-ai-client');
|
|
21
|
+
const upgradeMessage = createInterpolateElement(__('Not enough requests left to generate a logo. <strong>Upgrade now to increase it.</strong>', 'jetpack-ai-client'), {
|
|
22
|
+
strong: _jsx("strong", {}),
|
|
23
|
+
});
|
|
24
|
+
const { nextTierCheckoutURL: checkoutUrl } = useCheckout();
|
|
25
|
+
const { context } = useLogoGenerator();
|
|
26
|
+
const handleUpgradeClick = () => {
|
|
27
|
+
recordTracksEvent(EVENT_UPGRADE, { context, placement: EVENT_PLACEMENT_UPGRADE_PROMPT });
|
|
28
|
+
};
|
|
29
|
+
return (_jsx("div", { className: "jetpack-upgrade-plan-banner", children: _jsxs("div", { className: "jetpack-upgrade-plan-banner__wrapper", children: [_jsxs("div", { children: [_jsx(Icon, { className: "jetpack-upgrade-plan-banner__icon", icon: warning }), _jsx("span", { className: "jetpack-upgrade-plan-banner__banner-description", children: upgradeMessage })] }), _jsx(Button, { href: checkoutUrl, target: "_blank", className: "is-primary", onClick: handleUpgradeClick, children: buttonText })] }) }));
|
|
30
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { useAnalytics } from '@automattic/jetpack-shared-extension-utils';
|
|
6
|
+
import { Button } from '@wordpress/components';
|
|
7
|
+
import { __ } from '@wordpress/i18n';
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import { EVENT_PLACEMENT_FREE_USER_SCREEN, EVENT_UPGRADE } from '../constants.js';
|
|
12
|
+
import useLogoGenerator from '../hooks/use-logo-generator.js';
|
|
13
|
+
export const UpgradeScreen = ({ onCancel, upgradeURL, reason }) => {
|
|
14
|
+
const { tracks } = useAnalytics();
|
|
15
|
+
const { recordEvent: recordTracksEvent } = tracks;
|
|
16
|
+
const upgradeMessageFeature = __('Upgrade your Jetpack AI for access to exclusive features, including logo generation. This upgrade will also increase the amount of requests you can use in all AI-powered features.', 'jetpack-ai-client');
|
|
17
|
+
const upgradeMessageRequests = __('Not enough requests left to generate a logo. Upgrade your Jetpack AI to increase the amount of requests you can use in all AI-powered features.', 'jetpack-ai-client');
|
|
18
|
+
const { context } = useLogoGenerator();
|
|
19
|
+
const handleUpgradeClick = () => {
|
|
20
|
+
recordTracksEvent(EVENT_UPGRADE, { context, placement: EVENT_PLACEMENT_FREE_USER_SCREEN });
|
|
21
|
+
onCancel();
|
|
22
|
+
};
|
|
23
|
+
return (_jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-message-wrapper", children: [_jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-message", children: [_jsx("span", { className: "jetpack-ai-logo-generator-modal__loading-message", children: reason === 'feature' ? upgradeMessageFeature : upgradeMessageRequests }), "\u00A0", _jsx(Button, { variant: "link", href: "https://jetpack.com/ai/", target: "_blank", children: __('Learn more', 'jetpack-ai-client') })] }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal__notice-actions", children: [_jsx(Button, { variant: "tertiary", onClick: onCancel, children: __('Cancel', 'jetpack-ai-client') }), _jsx(Button, { variant: "primary", href: upgradeURL, target: "_blank", onClick: handleUpgradeClick, children: __('Upgrade', 'jetpack-ai-client') })] })] }));
|
|
24
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { Button, Icon } from '@wordpress/components';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
import { external } from '@wordpress/icons';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
/**
|
|
10
|
+
* Internal dependencies
|
|
11
|
+
*/
|
|
12
|
+
import jetpackLogo from '../assets/images/jetpack-logo.svg';
|
|
13
|
+
import './visit-site-banner.scss';
|
|
14
|
+
export const VisitSiteBanner = ({ className = null, siteURL = '#', onVisitBlankTarget }) => {
|
|
15
|
+
return (_jsxs("div", { className: clsx('jetpack-ai-logo-generator-modal-visit-site-banner', className), children: [_jsx("div", { className: "jetpack-ai-logo-generator-modal-visit-site-banner__jetpack-logo", children: _jsx("img", { src: jetpackLogo, alt: "Jetpack" }) }), _jsxs("div", { className: "jetpack-ai-logo-generator-modal-visit-site-banner__content", children: [_jsx("strong", { children: __('Do you want to know all the amazing things you can do with Jetpack AI?', 'jetpack-ai-client') }), _jsx("span", { children: __('Generate and tweak content, create forms, get feedback and much more.', 'jetpack-ai-client') }), _jsx("div", { children: _jsxs(Button, { variant: "link", href: siteURL, target: "_blank", onClick: onVisitBlankTarget, children: [__('Visit website', 'jetpack-ai-client'), _jsx(Icon, { icon: external, size: 20 })] }) })] })] }));
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const JWT_TOKEN_ID = "jetpack-ai-jwt";
|
|
2
|
+
export declare const JWT_TOKEN_EXPIRATION_TIME: number;
|
|
3
|
+
export declare const EVENT_MODAL_OPEN = "jetpack_ai_logo_generator_modal_open";
|
|
4
|
+
export declare const EVENT_MODAL_CLOSE = "jetpack_ai_logo_generator_modal_close";
|
|
5
|
+
export declare const EVENT_GENERATE = "jetpack_ai_logo_generator_generate";
|
|
6
|
+
export declare const EVENT_SAVE = "jetpack_ai_logo_generator_save";
|
|
7
|
+
export declare const EVENT_USE = "jetpack_ai_logo_generator_use";
|
|
8
|
+
export declare const EVENT_NAVIGATE = "jetpack_ai_logo_generator_navigate";
|
|
9
|
+
export declare const EVENT_FEEDBACK = "jetpack_ai_logo_generator_feedback";
|
|
10
|
+
export declare const EVENT_UPGRADE = "jetpack_ai_upgrade_button";
|
|
11
|
+
export declare const EVENT_PLACEMENT_QUICK_LINKS = "quick_links";
|
|
12
|
+
export declare const EVENT_PLACEMENT_INPUT_FOOTER = "input_footer";
|
|
13
|
+
export declare const EVENT_PLACEMENT_FREE_USER_SCREEN = "free_user_screen";
|
|
14
|
+
export declare const EVENT_PLACEMENT_UPGRADE_PROMPT = "upgrade_prompt";
|
|
15
|
+
export declare const MINIMUM_PROMPT_LENGTH = 3;
|
|
16
|
+
export declare const DEFAULT_LOGO_COST = 10;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const JWT_TOKEN_ID = 'jetpack-ai-jwt';
|
|
2
|
+
export const JWT_TOKEN_EXPIRATION_TIME = 2 * 60 * 1000; // 2 minutes
|
|
3
|
+
// Tracks event names
|
|
4
|
+
export const EVENT_MODAL_OPEN = 'jetpack_ai_logo_generator_modal_open';
|
|
5
|
+
export const EVENT_MODAL_CLOSE = 'jetpack_ai_logo_generator_modal_close';
|
|
6
|
+
export const EVENT_GENERATE = 'jetpack_ai_logo_generator_generate';
|
|
7
|
+
export const EVENT_SAVE = 'jetpack_ai_logo_generator_save';
|
|
8
|
+
export const EVENT_USE = 'jetpack_ai_logo_generator_use';
|
|
9
|
+
export const EVENT_NAVIGATE = 'jetpack_ai_logo_generator_navigate';
|
|
10
|
+
export const EVENT_FEEDBACK = 'jetpack_ai_logo_generator_feedback';
|
|
11
|
+
export const EVENT_UPGRADE = 'jetpack_ai_upgrade_button';
|
|
12
|
+
// Event placement constants
|
|
13
|
+
export const EVENT_PLACEMENT_QUICK_LINKS = 'quick_links';
|
|
14
|
+
export const EVENT_PLACEMENT_INPUT_FOOTER = 'input_footer';
|
|
15
|
+
export const EVENT_PLACEMENT_FREE_USER_SCREEN = 'free_user_screen';
|
|
16
|
+
export const EVENT_PLACEMENT_UPGRADE_PROMPT = 'upgrade_prompt';
|
|
17
|
+
// Feature constants
|
|
18
|
+
export const MINIMUM_PROMPT_LENGTH = 3;
|
|
19
|
+
export const DEFAULT_LOGO_COST = 10;
|