Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | 6x 1x 5x 5x 2x 2x 26x 63x 26x 26x 14x 14x 8x 8x 2x 8x 2x 8x 1x 8x 1x 8x 1x 8x 1x 7x 8x 8x 8x 6x 8x 1x 1x 8x | import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import apiFetch from '@wordpress/api-fetch';
type ApiSettings = {
videopress_videos_private_for_site: boolean;
videopress_auto_subtitles_disabled: boolean;
videopress_player_preload_disabled: boolean;
videopress_inline_player_enabled: boolean;
videopress_share_menu_disabled: boolean;
site_is_private: boolean;
site_type: string;
};
export type Settings = {
videoPressVideosPrivateForSite: boolean;
videoPressAutoSubtitlesDisabled: boolean;
videoPressPlayerPreloadDisabled: boolean;
videoPressInlinePlayerEnabled: boolean;
videoPressShareMenuDisabled: boolean;
siteIsPrivate: boolean;
siteType: string;
};
export type SettingsPatch = Partial<
Pick<
Settings,
| 'videoPressVideosPrivateForSite'
| 'videoPressAutoSubtitlesDisabled'
| 'videoPressPlayerPreloadDisabled'
| 'videoPressInlinePlayerEnabled'
| 'videoPressShareMenuDisabled'
>
>;
/**
* Whether `videoPressVideosPrivateForSite` is resolved server-side and therefore
* not independently writable from this screen.
*
* This mirrors `Data::get_videopress_videos_private_for_site()` on the server.
* WordPress.com Simple always derives VideoPress privacy from the whole-site
* Privacy setting (there is no independent option), so it is always locked.
* Private Atomic/WoA sites force every video private, locking the value to its
* effective (true) state. On public Atomic and self-hosted Jetpack the stored
* option is honored, so the toggle stays writable. Deciding from the settings
* response — not the ENV — keeps Simple and private Atomic in sync with what
* the server actually accepts.
*
* @param settings - The resolved settings data, or undefined while loading.
* @return true when the value is server-controlled (render it read-only).
*/
export function isPrivateForSiteServerControlled(
settings: Pick< Settings, 'siteType' | 'siteIsPrivate' > | undefined
): boolean {
if ( ! settings ) {
return false;
}
const { siteType, siteIsPrivate } = settings;
return siteType === 'simple' || ( siteType === 'atomic' && siteIsPrivate );
}
const QUERY_KEY = [ 'jetpack-videopress-settings' ] as const;
// One path for every host. The wpcom/v2 route exists everywhere (the package
// registers it through the standard WPCOM_REST_API_V2 loader) with host-safe
// callbacks, and it's the only namespace that reaches the REST dispatcher on
// WordPress.com Simple — videopress/v1 doesn't. Its videopress/v1/settings
// twin stays for the legacy dashboard and external consumers.
const SETTINGS_PATH = '/wpcom/v2/videopress/settings';
/**
* Convert a raw REST API settings object to the camelCase shape used in JS.
*
* @param raw - The snake_case settings object returned by the REST API.
* @return The camelCase Settings object used throughout the dashboard.
*/
function fromApi( raw: ApiSettings ): Settings {
return {
videoPressVideosPrivateForSite: raw.videopress_videos_private_for_site,
videoPressAutoSubtitlesDisabled: raw.videopress_auto_subtitles_disabled,
videoPressPlayerPreloadDisabled: raw.videopress_player_preload_disabled,
videoPressInlinePlayerEnabled: raw.videopress_inline_player_enabled,
videoPressShareMenuDisabled: raw.videopress_share_menu_disabled,
siteIsPrivate: raw.site_is_private,
siteType: raw.site_type,
};
}
/**
* Fetch the VideoPress site settings from the REST API.
*
* @return TanStack Query result containing the Settings object.
*/
export function useSettings() {
return useQuery< Settings >( {
queryKey: QUERY_KEY,
queryFn: async () => {
const raw = await apiFetch< ApiSettings >( { path: SETTINGS_PATH } );
return fromApi( raw );
},
staleTime: 5 * 60_000,
} );
}
/**
* Return a mutation for updating VideoPress site settings with optimistic updates.
* On success the cache is updated immediately; on error the previous value is restored.
*
* @return TanStack Mutation object for updating Settings.
*/
export function useUpdateSettings() {
const client = useQueryClient();
return useMutation< void, Error, SettingsPatch, { previous?: Settings } >( {
mutationFn: async patch => {
const data: Partial<
Pick<
ApiSettings,
| 'videopress_videos_private_for_site'
| 'videopress_auto_subtitles_disabled'
| 'videopress_player_preload_disabled'
| 'videopress_inline_player_enabled'
| 'videopress_share_menu_disabled'
>
> = {};
if ( patch.videoPressVideosPrivateForSite !== undefined ) {
data.videopress_videos_private_for_site = patch.videoPressVideosPrivateForSite;
}
if ( patch.videoPressAutoSubtitlesDisabled !== undefined ) {
data.videopress_auto_subtitles_disabled = patch.videoPressAutoSubtitlesDisabled;
}
if ( patch.videoPressPlayerPreloadDisabled !== undefined ) {
data.videopress_player_preload_disabled = patch.videoPressPlayerPreloadDisabled;
}
if ( patch.videoPressInlinePlayerEnabled !== undefined ) {
data.videopress_inline_player_enabled = patch.videoPressInlinePlayerEnabled;
}
if ( patch.videoPressShareMenuDisabled !== undefined ) {
data.videopress_share_menu_disabled = patch.videoPressShareMenuDisabled;
}
if ( Object.keys( data ).length === 0 ) {
return;
}
await apiFetch( {
path: SETTINGS_PATH,
method: 'POST',
data,
} );
},
onMutate: async patch => {
await client.cancelQueries( { queryKey: QUERY_KEY } );
const previous = client.getQueryData< Settings >( QUERY_KEY );
if ( previous ) {
client.setQueryData< Settings >( QUERY_KEY, { ...previous, ...patch } );
}
return { previous };
},
onError: ( _err, _patch, context ) => {
Eif ( context?.previous ) {
client.setQueryData( QUERY_KEY, context.previous );
}
},
onSettled: () => {
client.invalidateQueries( { queryKey: QUERY_KEY } );
},
} );
}
|