@automattic/jetpack-ai-client 0.16.4 → 0.18.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 +15 -0
- package/build/components/ai-control/extension-ai-control.d.ts +2 -1
- package/build/components/ai-control/extension-ai-control.js +5 -2
- package/build/components/message/index.d.ts +6 -0
- package/build/components/message/index.js +13 -0
- package/build/jwt/index.js +1 -1
- package/build/logo-generator/components/fair-usage-notice.d.ts +11 -0
- package/build/logo-generator/components/fair-usage-notice.js +19 -0
- package/build/logo-generator/components/generator-modal.js +13 -6
- package/build/logo-generator/components/history-carousel.js +6 -5
- package/build/logo-generator/components/logo-presenter.js +8 -3
- package/build/logo-generator/components/prompt.js +5 -4
- package/build/logo-generator/hooks/use-checkout.js +3 -2
- package/build/logo-generator/hooks/use-fair-usage-notice-message.d.ts +3 -0
- package/build/logo-generator/hooks/use-fair-usage-notice-message.js +43 -0
- package/build/logo-generator/hooks/use-logo-generator.d.ts +3 -0
- package/build/logo-generator/hooks/use-logo-generator.js +7 -2
- package/build/logo-generator/store/actions.d.ts +4 -0
- package/build/logo-generator/store/actions.js +8 -1
- package/build/logo-generator/store/constants.d.ts +1 -0
- package/build/logo-generator/store/constants.js +1 -0
- package/build/logo-generator/store/reducer.d.ts +37 -0
- package/build/logo-generator/store/reducer.js +10 -1
- package/build/logo-generator/store/selectors.d.ts +14 -0
- package/build/logo-generator/store/selectors.js +21 -0
- package/build/logo-generator/store/types.d.ts +13 -0
- package/package.json +13 -13
- package/src/components/ai-control/extension-ai-control.tsx +10 -1
- package/src/components/message/index.tsx +20 -0
- package/src/jwt/index.ts +1 -2
- package/src/logo-generator/components/fair-usage-notice.tsx +38 -0
- package/src/logo-generator/components/generator-modal.tsx +24 -7
- package/src/logo-generator/components/history-carousel.tsx +8 -1
- package/src/logo-generator/components/logo-presenter.tsx +16 -5
- package/src/logo-generator/components/prompt.tsx +8 -4
- package/src/logo-generator/hooks/use-checkout.ts +7 -2
- package/src/logo-generator/hooks/use-fair-usage-notice-message.tsx +68 -0
- package/src/logo-generator/hooks/use-logo-generator.ts +8 -0
- package/src/logo-generator/store/actions.ts +9 -0
- package/src/logo-generator/store/constants.ts +1 -0
- package/src/logo-generator/store/reducer.ts +12 -0
- package/src/logo-generator/store/selectors.ts +24 -0
- package/src/logo-generator/store/types.ts +13 -0
|
@@ -20,10 +20,11 @@ import type { Selectors } from '../store/types.js';
|
|
|
20
20
|
const debug = debugFactory( 'ai-client:logo-generator:use-checkout' );
|
|
21
21
|
|
|
22
22
|
export const useCheckout = () => {
|
|
23
|
-
const { nextTier } = useSelect( select => {
|
|
23
|
+
const { nextTier, tierPlansEnabled } = useSelect( select => {
|
|
24
24
|
const selectors: Selectors = select( STORE_NAME );
|
|
25
25
|
return {
|
|
26
26
|
nextTier: selectors.getAiAssistantFeature().nextTier,
|
|
27
|
+
tierPlansEnabled: selectors.getAiAssistantFeature().tierPlansEnabled,
|
|
27
28
|
};
|
|
28
29
|
}, [] );
|
|
29
30
|
|
|
@@ -33,7 +34,11 @@ export const useCheckout = () => {
|
|
|
33
34
|
const wpcomCheckoutUrl = new URL( `https://jetpack.com/redirect/` );
|
|
34
35
|
wpcomCheckoutUrl.searchParams.set( 'source', 'jetpack-ai-yearly-tier-upgrade-nudge' );
|
|
35
36
|
wpcomCheckoutUrl.searchParams.set( 'site', getSiteFragment() as string );
|
|
36
|
-
|
|
37
|
+
|
|
38
|
+
wpcomCheckoutUrl.searchParams.set(
|
|
39
|
+
'path',
|
|
40
|
+
tierPlansEnabled ? `jetpack_ai_yearly:-q-${ nextTier?.limit }` : 'jetpack_ai_yearly'
|
|
41
|
+
);
|
|
37
42
|
|
|
38
43
|
/**
|
|
39
44
|
* Open the product interstitial page
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useSelect } from '@wordpress/data';
|
|
2
|
+
import { createInterpolateElement } from '@wordpress/element';
|
|
3
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
4
|
+
/**
|
|
5
|
+
* Internal dependencies
|
|
6
|
+
*/
|
|
7
|
+
import { STORE_NAME } from '../store/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Types
|
|
10
|
+
*/
|
|
11
|
+
import type { Selectors } from '../store/types.js';
|
|
12
|
+
|
|
13
|
+
const useFairUsageNoticeMessage = () => {
|
|
14
|
+
const { usagePeriod } = useSelect( select => {
|
|
15
|
+
const selectors: Selectors = select( STORE_NAME );
|
|
16
|
+
return {
|
|
17
|
+
usagePeriod: selectors.getAiAssistantFeature().nextTier,
|
|
18
|
+
};
|
|
19
|
+
}, [] );
|
|
20
|
+
const getFormattedUsagePeriodStartDate = planUsagePeriod => {
|
|
21
|
+
if ( ! planUsagePeriod?.nextStart ) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const nextUsagePeriodStartDate = new Date( planUsagePeriod.nextStart );
|
|
26
|
+
return (
|
|
27
|
+
nextUsagePeriodStartDate.toLocaleString( 'default', { month: 'long' } ) +
|
|
28
|
+
' ' +
|
|
29
|
+
nextUsagePeriodStartDate.getDate()
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getFairUsageNoticeMessage = resetDateString => {
|
|
34
|
+
const fairUsageMessage = __(
|
|
35
|
+
"You've reached this month's request limit, per our <link>fair usage policy</link>.",
|
|
36
|
+
'jetpack-ai-client'
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
if ( ! resetDateString ) {
|
|
40
|
+
return fairUsageMessage;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Translators: %s is the date when the requests will reset.
|
|
44
|
+
const dateMessage = __( 'Requests will reset on %s.', 'jetpack-ai-client' );
|
|
45
|
+
const formattedDateMessage = sprintf( dateMessage, resetDateString );
|
|
46
|
+
|
|
47
|
+
return `${ fairUsageMessage } ${ formattedDateMessage }`;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const nextUsagePeriodStartDateString = getFormattedUsagePeriodStartDate( usagePeriod );
|
|
51
|
+
|
|
52
|
+
// Get the proper template based on the presence of the next usage period start date.
|
|
53
|
+
const fairUsageNoticeMessage = getFairUsageNoticeMessage( nextUsagePeriodStartDateString );
|
|
54
|
+
|
|
55
|
+
const fairUsageNoticeMessageElement = createInterpolateElement( fairUsageNoticeMessage, {
|
|
56
|
+
link: (
|
|
57
|
+
<a
|
|
58
|
+
href="https://jetpack.com/redirect/?source=ai-logo-generator-fair-usage-policy"
|
|
59
|
+
target="_blank"
|
|
60
|
+
rel="noreferrer"
|
|
61
|
+
/>
|
|
62
|
+
),
|
|
63
|
+
} );
|
|
64
|
+
|
|
65
|
+
return fairUsageNoticeMessageElement;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default useFairUsageNoticeMessage;
|
|
@@ -31,6 +31,7 @@ const useLogoGenerator = () => {
|
|
|
31
31
|
increaseAiAssistantRequestsCount,
|
|
32
32
|
addLogoToHistory,
|
|
33
33
|
setContext,
|
|
34
|
+
setIsLoadingHistory,
|
|
34
35
|
} = useDispatch( STORE_NAME );
|
|
35
36
|
|
|
36
37
|
const {
|
|
@@ -46,6 +47,8 @@ const useLogoGenerator = () => {
|
|
|
46
47
|
getAiAssistantFeature,
|
|
47
48
|
requireUpgrade,
|
|
48
49
|
context,
|
|
50
|
+
tierPlansEnabled,
|
|
51
|
+
isLoadingHistory,
|
|
49
52
|
} = useSelect( select => {
|
|
50
53
|
const selectors: Selectors = select( STORE_NAME );
|
|
51
54
|
|
|
@@ -62,6 +65,8 @@ const useLogoGenerator = () => {
|
|
|
62
65
|
getAiAssistantFeature: selectors.getAiAssistantFeature,
|
|
63
66
|
requireUpgrade: selectors.getRequireUpgrade(),
|
|
64
67
|
context: selectors.getContext(),
|
|
68
|
+
tierPlansEnabled: selectors.getTierPlansEnabled(),
|
|
69
|
+
isLoadingHistory: selectors.getIsLoadingHistory(),
|
|
65
70
|
};
|
|
66
71
|
}, [] );
|
|
67
72
|
|
|
@@ -383,6 +388,9 @@ User request:${ prompt }`;
|
|
|
383
388
|
getAiAssistantFeature,
|
|
384
389
|
requireUpgrade,
|
|
385
390
|
context,
|
|
391
|
+
tierPlansEnabled,
|
|
392
|
+
isLoadingHistory,
|
|
393
|
+
setIsLoadingHistory,
|
|
386
394
|
};
|
|
387
395
|
};
|
|
388
396
|
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
ACTION_SET_LOGO_UPDATE_ERROR,
|
|
29
29
|
ACTION_SET_SAVE_TO_LIBRARY_ERROR,
|
|
30
30
|
ACTION_SET_CONTEXT,
|
|
31
|
+
ACTION_SET_IS_LOADING_HISTORY,
|
|
31
32
|
} from './constants.js';
|
|
32
33
|
import type {
|
|
33
34
|
AiFeatureProps,
|
|
@@ -64,6 +65,7 @@ export function mapAiFeatureResponseToAiFeatureProps(
|
|
|
64
65
|
nextTier: response[ 'next-tier' ],
|
|
65
66
|
tierPlansEnabled: !! response[ 'tier-plans-enabled' ],
|
|
66
67
|
costs: response.costs,
|
|
68
|
+
featuresControl: response[ 'features-control' ],
|
|
67
69
|
};
|
|
68
70
|
}
|
|
69
71
|
|
|
@@ -246,6 +248,13 @@ const actions = {
|
|
|
246
248
|
context,
|
|
247
249
|
};
|
|
248
250
|
},
|
|
251
|
+
|
|
252
|
+
setIsLoadingHistory( isLoadingHistory: boolean ) {
|
|
253
|
+
return {
|
|
254
|
+
type: ACTION_SET_IS_LOADING_HISTORY,
|
|
255
|
+
isLoadingHistory,
|
|
256
|
+
};
|
|
257
|
+
},
|
|
249
258
|
};
|
|
250
259
|
|
|
251
260
|
export default actions;
|
|
@@ -37,6 +37,7 @@ export const ACTION_SAVE_SELECTED_LOGO = 'SAVE_SELECTED_LOGO';
|
|
|
37
37
|
export const ACTION_SET_IS_REQUESTING_IMAGE = 'SET_IS_REQUESTING_IMAGE';
|
|
38
38
|
export const ACTION_SET_IS_ENHANCING_PROMPT = 'SET_IS_ENHANCING_PROMPT';
|
|
39
39
|
export const ACTION_SET_SITE_HISTORY = 'SET_SITE_HISTORY';
|
|
40
|
+
export const ACTION_SET_IS_LOADING_HISTORY = 'SET_IS_LOADING_HISTORY';
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
43
|
* Logo generator error actions
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
ACTION_SET_SAVE_TO_LIBRARY_ERROR,
|
|
28
28
|
ACTION_SET_LOGO_UPDATE_ERROR,
|
|
29
29
|
ACTION_SET_CONTEXT,
|
|
30
|
+
ACTION_SET_IS_LOADING_HISTORY,
|
|
30
31
|
} from './constants.js';
|
|
31
32
|
import INITIAL_STATE from './initial-state.js';
|
|
32
33
|
import type {
|
|
@@ -61,6 +62,7 @@ import type { SiteDetails } from '../types.js';
|
|
|
61
62
|
* @param {Array< { url: string; description: string; mediaId?: number } >} action.history - The logo history
|
|
62
63
|
* @param {RequestError} action.error - The error to set
|
|
63
64
|
* @param {string} action.context - The context where the tool is being used
|
|
65
|
+
* @param {boolean} action.isLoadingHistory - Whether the history is being loaded
|
|
64
66
|
* @return {LogoGeneratorStateProp} The new state
|
|
65
67
|
*/
|
|
66
68
|
export default function reducer(
|
|
@@ -83,6 +85,7 @@ export default function reducer(
|
|
|
83
85
|
history?: Array< { url: string; description: string; mediaId?: number } >;
|
|
84
86
|
error?: RequestError;
|
|
85
87
|
context?: string;
|
|
88
|
+
isLoadingHistory?: boolean;
|
|
86
89
|
}
|
|
87
90
|
) {
|
|
88
91
|
switch ( action.type ) {
|
|
@@ -381,6 +384,15 @@ export default function reducer(
|
|
|
381
384
|
context: action.context,
|
|
382
385
|
},
|
|
383
386
|
};
|
|
387
|
+
|
|
388
|
+
case ACTION_SET_IS_LOADING_HISTORY:
|
|
389
|
+
return {
|
|
390
|
+
...state,
|
|
391
|
+
_meta: {
|
|
392
|
+
...( state._meta ?? {} ),
|
|
393
|
+
isLoadingHistory: action.isLoadingHistory,
|
|
394
|
+
},
|
|
395
|
+
};
|
|
384
396
|
}
|
|
385
397
|
|
|
386
398
|
return state;
|
|
@@ -121,6 +121,10 @@ const selectors = {
|
|
|
121
121
|
*/
|
|
122
122
|
getRequireUpgrade( state: LogoGeneratorStateProp ): boolean {
|
|
123
123
|
const feature = state.features.aiAssistantFeature;
|
|
124
|
+
|
|
125
|
+
if ( ! feature?.tierPlansEnabled ) {
|
|
126
|
+
return feature?.requireUpgrade;
|
|
127
|
+
}
|
|
124
128
|
const logoCost = feature?.costs?.[ 'jetpack-ai-logo-generator' ]?.logo ?? DEFAULT_LOGO_COST;
|
|
125
129
|
const currentLimit = feature?.currentTier?.value || 0;
|
|
126
130
|
const currentUsage = feature?.usagePeriod?.requestsCount || 0;
|
|
@@ -196,6 +200,26 @@ const selectors = {
|
|
|
196
200
|
getContext( state: LogoGeneratorStateProp ): string {
|
|
197
201
|
return state._meta?.context ?? '';
|
|
198
202
|
},
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Get tier plans enabled status.
|
|
206
|
+
*
|
|
207
|
+
* @param {LogoGeneratorStateProp} state - The app state tree.
|
|
208
|
+
* @return {boolean} The tier plans enabled status.
|
|
209
|
+
*/
|
|
210
|
+
getTierPlansEnabled( state: LogoGeneratorStateProp ): boolean {
|
|
211
|
+
return state.features.aiAssistantFeature?.tierPlansEnabled ?? false;
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get tier plans enabled status.
|
|
216
|
+
*
|
|
217
|
+
* @param {LogoGeneratorStateProp} state - The app state tree.
|
|
218
|
+
* @return {boolean} The loading logo history status.
|
|
219
|
+
*/
|
|
220
|
+
getIsLoadingHistory( state: LogoGeneratorStateProp ): boolean {
|
|
221
|
+
return state._meta?.isLoadingHistory ?? false;
|
|
222
|
+
},
|
|
199
223
|
};
|
|
200
224
|
|
|
201
225
|
export default selectors;
|
|
@@ -88,6 +88,14 @@ export type TierValueProp =
|
|
|
88
88
|
| Tier750Props[ 'value' ]
|
|
89
89
|
| Tier1000Props[ 'value' ];
|
|
90
90
|
|
|
91
|
+
export type FeatureControl = {
|
|
92
|
+
enabled: boolean;
|
|
93
|
+
'min-jetpack-version': string;
|
|
94
|
+
[ key: string ]: FeatureControl | boolean | string;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export type FeaturesControl = { [ key: string ]: FeatureControl };
|
|
98
|
+
|
|
91
99
|
export type AiFeatureProps = {
|
|
92
100
|
hasFeature: boolean;
|
|
93
101
|
isOverLimit: boolean;
|
|
@@ -110,6 +118,7 @@ export type AiFeatureProps = {
|
|
|
110
118
|
logo: number;
|
|
111
119
|
};
|
|
112
120
|
};
|
|
121
|
+
featuresControl?: FeaturesControl;
|
|
113
122
|
};
|
|
114
123
|
|
|
115
124
|
// Type used in the `wordpress-com/plans` store.
|
|
@@ -143,6 +152,7 @@ export type LogoGeneratorStateProp = {
|
|
|
143
152
|
saveToLibraryError?: RequestError;
|
|
144
153
|
logoUpdateError?: RequestError;
|
|
145
154
|
context: string;
|
|
155
|
+
isLoadingHistory: boolean;
|
|
146
156
|
};
|
|
147
157
|
siteDetails?: SiteDetails | Record< string, never >;
|
|
148
158
|
features: {
|
|
@@ -172,6 +182,8 @@ export type Selectors = {
|
|
|
172
182
|
getSaveToLibraryError(): RequestError;
|
|
173
183
|
getLogoUpdateError(): RequestError;
|
|
174
184
|
getContext(): string;
|
|
185
|
+
getTierPlansEnabled(): boolean;
|
|
186
|
+
getIsLoadingHistory(): boolean;
|
|
175
187
|
};
|
|
176
188
|
|
|
177
189
|
/*
|
|
@@ -202,6 +214,7 @@ export type AiAssistantFeatureEndpointResponseProps = {
|
|
|
202
214
|
logo: number;
|
|
203
215
|
};
|
|
204
216
|
};
|
|
217
|
+
'features-control'?: FeaturesControl;
|
|
205
218
|
};
|
|
206
219
|
|
|
207
220
|
export type SaveLogo = ( logo: Logo ) => Promise< { mediaId: number; mediaURL: string } >;
|