@pranaysahith/decap-cms-core 3.9.1
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/README.md +9 -0
- package/dist/@pranaysahith/decap-cms-core.js +52 -0
- package/dist/@pranaysahith/decap-cms-core.js.LICENSE.txt +141 -0
- package/dist/@pranaysahith/decap-cms-core.js.map +1 -0
- package/dist/decap-cms-core.js +47 -0
- package/dist/decap-cms-core.js.LICENSE.txt +116 -0
- package/dist/decap-cms-core.js.map +1 -0
- package/dist/esm/actions/auth.js +97 -0
- package/dist/esm/actions/collections.js +15 -0
- package/dist/esm/actions/config.js +493 -0
- package/dist/esm/actions/deploys.js +79 -0
- package/dist/esm/actions/editorialWorkflow.js +480 -0
- package/dist/esm/actions/entries.js +865 -0
- package/dist/esm/actions/media.js +147 -0
- package/dist/esm/actions/mediaLibrary.js +552 -0
- package/dist/esm/actions/notifications.js +21 -0
- package/dist/esm/actions/search.js +149 -0
- package/dist/esm/actions/status.js +74 -0
- package/dist/esm/actions/waitUntil.js +32 -0
- package/dist/esm/backend.js +1082 -0
- package/dist/esm/bootstrap.js +101 -0
- package/dist/esm/components/App/App.js +289 -0
- package/dist/esm/components/App/Header.js +172 -0
- package/dist/esm/components/App/NotFoundPage.js +19 -0
- package/dist/esm/components/Collection/Collection.js +198 -0
- package/dist/esm/components/Collection/CollectionControls.js +46 -0
- package/dist/esm/components/Collection/CollectionSearch.js +222 -0
- package/dist/esm/components/Collection/CollectionTop.js +68 -0
- package/dist/esm/components/Collection/ControlButton.js +17 -0
- package/dist/esm/components/Collection/Entries/Entries.js +73 -0
- package/dist/esm/components/Collection/Entries/EntriesCollection.js +241 -0
- package/dist/esm/components/Collection/Entries/EntriesSearch.js +113 -0
- package/dist/esm/components/Collection/Entries/EntryCard.js +177 -0
- package/dist/esm/components/Collection/Entries/EntryListing.js +143 -0
- package/dist/esm/components/Collection/FilterControl.js +33 -0
- package/dist/esm/components/Collection/FolderRenameControl.js +403 -0
- package/dist/esm/components/Collection/GroupControl.js +33 -0
- package/dist/esm/components/Collection/NestedCollection.js +308 -0
- package/dist/esm/components/Collection/Sidebar.js +91 -0
- package/dist/esm/components/Collection/SortControl.js +59 -0
- package/dist/esm/components/Collection/ViewStyleControl.js +38 -0
- package/dist/esm/components/Editor/Editor.js +466 -0
- package/dist/esm/components/Editor/EditorControlPane/EditorControl.js +395 -0
- package/dist/esm/components/Editor/EditorControlPane/EditorControlPane.js +254 -0
- package/dist/esm/components/Editor/EditorControlPane/Widget.js +374 -0
- package/dist/esm/components/Editor/EditorInterface.js +386 -0
- package/dist/esm/components/Editor/EditorPreviewPane/EditorPreview.js +47 -0
- package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewContent.js +66 -0
- package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +288 -0
- package/dist/esm/components/Editor/EditorPreviewPane/PreviewHOC.js +27 -0
- package/dist/esm/components/Editor/EditorToolbar.js +536 -0
- package/dist/esm/components/Editor/EntryPathEditor.js +272 -0
- package/dist/esm/components/Editor/withWorkflow.js +56 -0
- package/dist/esm/components/EditorWidgets/Unknown/UnknownControl.js +18 -0
- package/dist/esm/components/EditorWidgets/Unknown/UnknownPreview.js +20 -0
- package/dist/esm/components/EditorWidgets/index.js +4 -0
- package/dist/esm/components/MediaLibrary/EmptyMessage.js +22 -0
- package/dist/esm/components/MediaLibrary/MediaLibrary.js +446 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryButtons.js +93 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryCard.js +99 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryCardGrid.js +198 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryHeader.js +32 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryModal.js +156 -0
- package/dist/esm/components/MediaLibrary/MediaLibrarySearch.js +51 -0
- package/dist/esm/components/MediaLibrary/MediaLibraryTop.js +123 -0
- package/dist/esm/components/UI/DragDrop.js +67 -0
- package/dist/esm/components/UI/ErrorBoundary.js +173 -0
- package/dist/esm/components/UI/FileUploadButton.js +27 -0
- package/dist/esm/components/UI/Modal.js +104 -0
- package/dist/esm/components/UI/Notifications.js +62 -0
- package/dist/esm/components/UI/SettingsDropdown.js +107 -0
- package/dist/esm/components/UI/index.js +6 -0
- package/dist/esm/components/Workflow/Workflow.js +133 -0
- package/dist/esm/components/Workflow/WorkflowCard.js +128 -0
- package/dist/esm/components/Workflow/WorkflowList.js +204 -0
- package/dist/esm/constants/collectionTypes.js +2 -0
- package/dist/esm/constants/collectionViews.js +2 -0
- package/dist/esm/constants/commitProps.js +2 -0
- package/dist/esm/constants/configSchema.js +644 -0
- package/dist/esm/constants/fieldInference.js +57 -0
- package/dist/esm/constants/publishModes.js +18 -0
- package/dist/esm/constants/validationErrorTypes.js +6 -0
- package/dist/esm/formats/formats.js +83 -0
- package/dist/esm/formats/frontmatter.js +146 -0
- package/dist/esm/formats/helpers.js +12 -0
- package/dist/esm/formats/json.js +8 -0
- package/dist/esm/formats/toml.js +32 -0
- package/dist/esm/formats/yaml.js +51 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/integrations/index.js +28 -0
- package/dist/esm/integrations/providers/algolia/implementation.js +174 -0
- package/dist/esm/integrations/providers/assetStore/implementation.js +165 -0
- package/dist/esm/lib/consoleError.js +3 -0
- package/dist/esm/lib/formatters.js +191 -0
- package/dist/esm/lib/i18n.js +367 -0
- package/dist/esm/lib/phrases.js +6 -0
- package/dist/esm/lib/polyfill.js +8 -0
- package/dist/esm/lib/registry.js +329 -0
- package/dist/esm/lib/serializeEntryValues.js +67 -0
- package/dist/esm/lib/stega.js +142 -0
- package/dist/esm/lib/textHelper.js +9 -0
- package/dist/esm/lib/urlHelper.js +111 -0
- package/dist/esm/mediaLibrary.js +37 -0
- package/dist/esm/reducers/auth.js +27 -0
- package/dist/esm/reducers/collections.js +428 -0
- package/dist/esm/reducers/combinedReducer.js +8 -0
- package/dist/esm/reducers/config.js +29 -0
- package/dist/esm/reducers/cursors.js +31 -0
- package/dist/esm/reducers/deploys.js +45 -0
- package/dist/esm/reducers/editorialWorkflow.js +83 -0
- package/dist/esm/reducers/entries.js +568 -0
- package/dist/esm/reducers/entryDraft.js +212 -0
- package/dist/esm/reducers/globalUI.js +25 -0
- package/dist/esm/reducers/index.js +66 -0
- package/dist/esm/reducers/integrations.js +53 -0
- package/dist/esm/reducers/mediaLibrary.js +252 -0
- package/dist/esm/reducers/medias.js +68 -0
- package/dist/esm/reducers/notifications.js +23 -0
- package/dist/esm/reducers/search.js +92 -0
- package/dist/esm/reducers/status.js +30 -0
- package/dist/esm/redux/index.js +7 -0
- package/dist/esm/redux/middleware/waitUntilAction.js +48 -0
- package/dist/esm/routing/history.js +12 -0
- package/dist/esm/types/diacritics.d.js +0 -0
- package/dist/esm/types/global.d.js +1 -0
- package/dist/esm/types/immutable.js +7 -0
- package/dist/esm/types/redux.js +14 -0
- package/dist/esm/types/tomlify-j0.4.d.js +0 -0
- package/dist/esm/valueObjects/AssetProxy.js +44 -0
- package/dist/esm/valueObjects/EditorComponent.js +34 -0
- package/dist/esm/valueObjects/Entry.js +20 -0
- package/index.d.ts +618 -0
- package/package.json +106 -0
- package/src/__tests__/backend.spec.js +1161 -0
- package/src/actions/__tests__/config.spec.js +1009 -0
- package/src/actions/__tests__/editorialWorkflow.spec.js +216 -0
- package/src/actions/__tests__/entries.spec.js +596 -0
- package/src/actions/__tests__/media.spec.ts +171 -0
- package/src/actions/__tests__/mediaLibrary.spec.js +327 -0
- package/src/actions/__tests__/search.spec.js +209 -0
- package/src/actions/auth.ts +127 -0
- package/src/actions/collections.ts +18 -0
- package/src/actions/config.ts +565 -0
- package/src/actions/deploys.ts +104 -0
- package/src/actions/editorialWorkflow.ts +567 -0
- package/src/actions/entries.ts +1055 -0
- package/src/actions/media.ts +139 -0
- package/src/actions/mediaLibrary.ts +574 -0
- package/src/actions/notifications.ts +36 -0
- package/src/actions/search.ts +221 -0
- package/src/actions/status.ts +99 -0
- package/src/actions/waitUntil.ts +49 -0
- package/src/backend.ts +1400 -0
- package/src/bootstrap.js +104 -0
- package/src/components/App/App.js +286 -0
- package/src/components/App/Header.js +266 -0
- package/src/components/App/NotFoundPage.js +23 -0
- package/src/components/Collection/Collection.js +210 -0
- package/src/components/Collection/CollectionControls.js +58 -0
- package/src/components/Collection/CollectionSearch.js +243 -0
- package/src/components/Collection/CollectionTop.js +81 -0
- package/src/components/Collection/ControlButton.js +27 -0
- package/src/components/Collection/Entries/Entries.js +82 -0
- package/src/components/Collection/Entries/EntriesCollection.js +277 -0
- package/src/components/Collection/Entries/EntriesSearch.js +102 -0
- package/src/components/Collection/Entries/EntryCard.js +246 -0
- package/src/components/Collection/Entries/EntryListing.js +151 -0
- package/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js +163 -0
- package/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap +46 -0
- package/src/components/Collection/FilterControl.js +39 -0
- package/src/components/Collection/GroupControl.js +39 -0
- package/src/components/Collection/NestedCollection.js +330 -0
- package/src/components/Collection/Sidebar.js +136 -0
- package/src/components/Collection/SortControl.js +68 -0
- package/src/components/Collection/ViewStyleControl.js +50 -0
- package/src/components/Collection/__tests__/Collection.spec.js +75 -0
- package/src/components/Collection/__tests__/NestedCollection.spec.js +445 -0
- package/src/components/Collection/__tests__/Sidebar.spec.js +87 -0
- package/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap +144 -0
- package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +550 -0
- package/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap +312 -0
- package/src/components/Editor/Editor.js +497 -0
- package/src/components/Editor/EditorControlPane/EditorControl.js +452 -0
- package/src/components/Editor/EditorControlPane/EditorControlPane.js +269 -0
- package/src/components/Editor/EditorControlPane/Widget.js +384 -0
- package/src/components/Editor/EditorInterface.js +444 -0
- package/src/components/Editor/EditorPreviewPane/EditorPreview.js +40 -0
- package/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js +74 -0
- package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +333 -0
- package/src/components/Editor/EditorPreviewPane/PreviewHOC.js +33 -0
- package/src/components/Editor/EditorToolbar.js +691 -0
- package/src/components/Editor/__tests__/Editor.spec.js +221 -0
- package/src/components/Editor/__tests__/EditorToolbar.spec.js +120 -0
- package/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap +45 -0
- package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +4233 -0
- package/src/components/Editor/withWorkflow.js +61 -0
- package/src/components/EditorWidgets/Unknown/UnknownControl.js +17 -0
- package/src/components/EditorWidgets/Unknown/UnknownPreview.js +19 -0
- package/src/components/EditorWidgets/index.js +5 -0
- package/src/components/MediaLibrary/EmptyMessage.js +28 -0
- package/src/components/MediaLibrary/MediaLibrary.js +411 -0
- package/src/components/MediaLibrary/MediaLibraryButtons.js +136 -0
- package/src/components/MediaLibrary/MediaLibraryCard.js +128 -0
- package/src/components/MediaLibrary/MediaLibraryCardGrid.js +199 -0
- package/src/components/MediaLibrary/MediaLibraryHeader.js +48 -0
- package/src/components/MediaLibrary/MediaLibraryModal.js +200 -0
- package/src/components/MediaLibrary/MediaLibrarySearch.js +61 -0
- package/src/components/MediaLibrary/MediaLibraryTop.js +143 -0
- package/src/components/MediaLibrary/__tests__/MediaLibraryButtons.spec.js +45 -0
- package/src/components/MediaLibrary/__tests__/MediaLibraryCard.spec.js +49 -0
- package/src/components/MediaLibrary/__tests__/__snapshots__/MediaLibraryCard.spec.js.snap +264 -0
- package/src/components/UI/DragDrop.js +66 -0
- package/src/components/UI/ErrorBoundary.js +214 -0
- package/src/components/UI/FileUploadButton.js +24 -0
- package/src/components/UI/Modal.js +112 -0
- package/src/components/UI/Notifications.tsx +83 -0
- package/src/components/UI/SettingsDropdown.js +103 -0
- package/src/components/UI/__tests__/ErrorBoundary.spec.js +57 -0
- package/src/components/UI/index.js +6 -0
- package/src/components/Workflow/Workflow.js +169 -0
- package/src/components/Workflow/WorkflowCard.js +177 -0
- package/src/components/Workflow/WorkflowList.js +272 -0
- package/src/constants/__tests__/configSchema.spec.js +611 -0
- package/src/constants/collectionTypes.ts +2 -0
- package/src/constants/collectionViews.js +2 -0
- package/src/constants/commitProps.ts +2 -0
- package/src/constants/configSchema.js +441 -0
- package/src/constants/fieldInference.tsx +78 -0
- package/src/constants/publishModes.ts +22 -0
- package/src/constants/validationErrorTypes.js +6 -0
- package/src/formats/__tests__/formats.spec.js +87 -0
- package/src/formats/__tests__/frontmatter.spec.js +429 -0
- package/src/formats/__tests__/toml.spec.js +9 -0
- package/src/formats/__tests__/yaml.spec.js +162 -0
- package/src/formats/formats.ts +97 -0
- package/src/formats/frontmatter.ts +150 -0
- package/src/formats/helpers.ts +14 -0
- package/src/formats/json.ts +9 -0
- package/src/formats/toml.ts +33 -0
- package/src/formats/yaml.ts +58 -0
- package/src/index.js +8 -0
- package/src/integrations/index.js +35 -0
- package/src/integrations/providers/algolia/implementation.js +176 -0
- package/src/integrations/providers/assetStore/implementation.js +148 -0
- package/src/lib/__tests__/formatters.spec.js +751 -0
- package/src/lib/__tests__/i18n.spec.js +792 -0
- package/src/lib/__tests__/phrases.spec.js +119 -0
- package/src/lib/__tests__/registry.spec.js +261 -0
- package/src/lib/__tests__/serializeEntryValues.spec.js +22 -0
- package/src/lib/__tests__/urlHelper.spec.js +138 -0
- package/src/lib/consoleError.js +7 -0
- package/src/lib/formatters.ts +286 -0
- package/src/lib/i18n.ts +454 -0
- package/src/lib/phrases.js +8 -0
- package/src/lib/polyfill.js +9 -0
- package/src/lib/registry.js +312 -0
- package/src/lib/serializeEntryValues.js +75 -0
- package/src/lib/stega.ts +145 -0
- package/src/lib/textHelper.js +11 -0
- package/src/lib/urlHelper.ts +128 -0
- package/src/mediaLibrary.ts +51 -0
- package/src/reducers/__tests__/auth.spec.ts +38 -0
- package/src/reducers/__tests__/collections.spec.js +610 -0
- package/src/reducers/__tests__/config.spec.js +38 -0
- package/src/reducers/__tests__/entries.spec.js +694 -0
- package/src/reducers/__tests__/entryDraft.spec.js +297 -0
- package/src/reducers/__tests__/globalUI.js +43 -0
- package/src/reducers/__tests__/integrations.spec.ts +76 -0
- package/src/reducers/__tests__/mediaLibrary.spec.js +154 -0
- package/src/reducers/__tests__/medias.spec.ts +49 -0
- package/src/reducers/auth.ts +46 -0
- package/src/reducers/collections.ts +535 -0
- package/src/reducers/combinedReducer.ts +11 -0
- package/src/reducers/config.ts +38 -0
- package/src/reducers/cursors.js +36 -0
- package/src/reducers/deploys.ts +52 -0
- package/src/reducers/editorialWorkflow.ts +163 -0
- package/src/reducers/entries.ts +819 -0
- package/src/reducers/entryDraft.js +260 -0
- package/src/reducers/globalUI.ts +45 -0
- package/src/reducers/index.ts +82 -0
- package/src/reducers/integrations.ts +59 -0
- package/src/reducers/mediaLibrary.ts +296 -0
- package/src/reducers/medias.ts +66 -0
- package/src/reducers/notifications.ts +52 -0
- package/src/reducers/search.ts +111 -0
- package/src/reducers/status.ts +40 -0
- package/src/redux/index.ts +18 -0
- package/src/redux/middleware/waitUntilAction.ts +64 -0
- package/src/routing/__tests__/history.spec.ts +49 -0
- package/src/routing/history.ts +17 -0
- package/src/types/diacritics.d.ts +1 -0
- package/src/types/global.d.ts +8 -0
- package/src/types/immutable.ts +49 -0
- package/src/types/redux.ts +827 -0
- package/src/types/tomlify-j0.4.d.ts +13 -0
- package/src/valueObjects/AssetProxy.ts +48 -0
- package/src/valueObjects/EditorComponent.js +38 -0
- package/src/valueObjects/Entry.ts +63 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { isAbsolutePath } from 'decap-cms-lib-util';
|
|
2
|
+
import { createAssetProxy } from '../valueObjects/AssetProxy';
|
|
3
|
+
import { selectMediaFilePath } from '../reducers/entries';
|
|
4
|
+
import { selectMediaFileByPath } from '../reducers/mediaLibrary';
|
|
5
|
+
import { getMediaFile, waitForMediaLibraryToLoad, getMediaDisplayURL } from './mediaLibrary';
|
|
6
|
+
export const ADD_ASSETS = 'ADD_ASSETS';
|
|
7
|
+
export const ADD_ASSET = 'ADD_ASSET';
|
|
8
|
+
export const REMOVE_ASSET = 'REMOVE_ASSET';
|
|
9
|
+
export const LOAD_ASSET_REQUEST = 'LOAD_ASSET_REQUEST';
|
|
10
|
+
export const LOAD_ASSET_SUCCESS = 'LOAD_ASSET_SUCCESS';
|
|
11
|
+
export const LOAD_ASSET_FAILURE = 'LOAD_ASSET_FAILURE';
|
|
12
|
+
export function addAssets(assets) {
|
|
13
|
+
return {
|
|
14
|
+
type: ADD_ASSETS,
|
|
15
|
+
payload: assets
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function addAsset(assetProxy) {
|
|
19
|
+
return {
|
|
20
|
+
type: ADD_ASSET,
|
|
21
|
+
payload: assetProxy
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function removeAsset(path) {
|
|
25
|
+
return {
|
|
26
|
+
type: REMOVE_ASSET,
|
|
27
|
+
payload: path
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function loadAssetRequest(path) {
|
|
31
|
+
return {
|
|
32
|
+
type: LOAD_ASSET_REQUEST,
|
|
33
|
+
payload: {
|
|
34
|
+
path
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function loadAssetSuccess(path) {
|
|
39
|
+
return {
|
|
40
|
+
type: LOAD_ASSET_SUCCESS,
|
|
41
|
+
payload: {
|
|
42
|
+
path
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function loadAssetFailure(path, error) {
|
|
47
|
+
return {
|
|
48
|
+
type: LOAD_ASSET_FAILURE,
|
|
49
|
+
payload: {
|
|
50
|
+
path,
|
|
51
|
+
error
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function loadAsset(resolvedPath) {
|
|
56
|
+
return async (dispatch, getState) => {
|
|
57
|
+
try {
|
|
58
|
+
dispatch(loadAssetRequest(resolvedPath));
|
|
59
|
+
// load asset url from backend
|
|
60
|
+
await waitForMediaLibraryToLoad(dispatch, getState());
|
|
61
|
+
const file = selectMediaFileByPath(getState(), resolvedPath);
|
|
62
|
+
if (file) {
|
|
63
|
+
const url = await getMediaDisplayURL(dispatch, getState(), file);
|
|
64
|
+
const asset = createAssetProxy({
|
|
65
|
+
path: resolvedPath,
|
|
66
|
+
url: url || resolvedPath
|
|
67
|
+
});
|
|
68
|
+
dispatch(addAsset(asset));
|
|
69
|
+
} else {
|
|
70
|
+
const {
|
|
71
|
+
url
|
|
72
|
+
} = await getMediaFile(getState(), resolvedPath);
|
|
73
|
+
const asset = createAssetProxy({
|
|
74
|
+
path: resolvedPath,
|
|
75
|
+
url
|
|
76
|
+
});
|
|
77
|
+
dispatch(addAsset(asset));
|
|
78
|
+
}
|
|
79
|
+
dispatch(loadAssetSuccess(resolvedPath));
|
|
80
|
+
} catch (e) {
|
|
81
|
+
dispatch(loadAssetFailure(resolvedPath, e));
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const emptyAsset = createAssetProxy({
|
|
86
|
+
path: 'empty.svg',
|
|
87
|
+
file: new File([`<svg xmlns="http://www.w3.org/2000/svg"></svg>`], 'empty.svg', {
|
|
88
|
+
type: 'image/svg+xml'
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
export function boundGetAsset(dispatch, collection, entry) {
|
|
92
|
+
function bound(path, field) {
|
|
93
|
+
const asset = dispatch(getAsset({
|
|
94
|
+
collection,
|
|
95
|
+
entry,
|
|
96
|
+
path,
|
|
97
|
+
field
|
|
98
|
+
}));
|
|
99
|
+
return asset;
|
|
100
|
+
}
|
|
101
|
+
return bound;
|
|
102
|
+
}
|
|
103
|
+
export function getAsset({
|
|
104
|
+
collection,
|
|
105
|
+
entry,
|
|
106
|
+
path,
|
|
107
|
+
field
|
|
108
|
+
}) {
|
|
109
|
+
return (dispatch, getState) => {
|
|
110
|
+
if (!path) return emptyAsset;
|
|
111
|
+
const state = getState();
|
|
112
|
+
const resolvedPath = selectMediaFilePath(state.config, collection, entry, path, field);
|
|
113
|
+
let {
|
|
114
|
+
asset,
|
|
115
|
+
isLoading,
|
|
116
|
+
error
|
|
117
|
+
} = state.medias[resolvedPath] || {};
|
|
118
|
+
if (isLoading) {
|
|
119
|
+
return emptyAsset;
|
|
120
|
+
}
|
|
121
|
+
if (asset) {
|
|
122
|
+
// There is already an AssetProxy in memory for this path. Use it.
|
|
123
|
+
return asset;
|
|
124
|
+
}
|
|
125
|
+
if (isAbsolutePath(resolvedPath)) {
|
|
126
|
+
// asset path is a public url so we can just use it as is
|
|
127
|
+
asset = createAssetProxy({
|
|
128
|
+
path: resolvedPath,
|
|
129
|
+
url: path
|
|
130
|
+
});
|
|
131
|
+
dispatch(addAsset(asset));
|
|
132
|
+
} else {
|
|
133
|
+
if (error) {
|
|
134
|
+
// on load error default back to original path
|
|
135
|
+
asset = createAssetProxy({
|
|
136
|
+
path: resolvedPath,
|
|
137
|
+
url: path
|
|
138
|
+
});
|
|
139
|
+
dispatch(addAsset(asset));
|
|
140
|
+
} else {
|
|
141
|
+
dispatch(loadAsset(resolvedPath));
|
|
142
|
+
asset = emptyAsset;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return asset;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
import { Map } from 'immutable';
|
|
2
|
+
import { basename, getBlobSHA } from 'decap-cms-lib-util';
|
|
3
|
+
import { currentBackend } from '../backend';
|
|
4
|
+
import { createAssetProxy } from '../valueObjects/AssetProxy';
|
|
5
|
+
import { selectIntegration } from '../reducers';
|
|
6
|
+
import { selectMediaFilePath, selectMediaFilePublicPath, selectEditingDraft } from '../reducers/entries';
|
|
7
|
+
import { selectMediaDisplayURL, selectMediaFiles } from '../reducers/mediaLibrary';
|
|
8
|
+
import { getIntegrationProvider } from '../integrations';
|
|
9
|
+
import { addAsset, removeAsset } from './media';
|
|
10
|
+
import { addDraftEntryMediaFile, removeDraftEntryMediaFile } from './entries';
|
|
11
|
+
import { sanitizeSlug } from '../lib/urlHelper';
|
|
12
|
+
import { waitUntilWithTimeout } from './waitUntil';
|
|
13
|
+
import { addNotification } from './notifications';
|
|
14
|
+
export const MEDIA_LIBRARY_OPEN = 'MEDIA_LIBRARY_OPEN';
|
|
15
|
+
export const MEDIA_LIBRARY_CLOSE = 'MEDIA_LIBRARY_CLOSE';
|
|
16
|
+
export const MEDIA_LIBRARY_CREATE = 'MEDIA_LIBRARY_CREATE';
|
|
17
|
+
export const MEDIA_INSERT = 'MEDIA_INSERT';
|
|
18
|
+
export const MEDIA_REMOVE_INSERTED = 'MEDIA_REMOVE_INSERTED';
|
|
19
|
+
export const MEDIA_LOAD_REQUEST = 'MEDIA_LOAD_REQUEST';
|
|
20
|
+
export const MEDIA_LOAD_SUCCESS = 'MEDIA_LOAD_SUCCESS';
|
|
21
|
+
export const MEDIA_LOAD_FAILURE = 'MEDIA_LOAD_FAILURE';
|
|
22
|
+
export const MEDIA_PERSIST_REQUEST = 'MEDIA_PERSIST_REQUEST';
|
|
23
|
+
export const MEDIA_PERSIST_SUCCESS = 'MEDIA_PERSIST_SUCCESS';
|
|
24
|
+
export const MEDIA_PERSIST_FAILURE = 'MEDIA_PERSIST_FAILURE';
|
|
25
|
+
export const MEDIA_DELETE_REQUEST = 'MEDIA_DELETE_REQUEST';
|
|
26
|
+
export const MEDIA_DELETE_SUCCESS = 'MEDIA_DELETE_SUCCESS';
|
|
27
|
+
export const MEDIA_DELETE_FAILURE = 'MEDIA_DELETE_FAILURE';
|
|
28
|
+
export const MEDIA_DISPLAY_URL_REQUEST = 'MEDIA_DISPLAY_URL_REQUEST';
|
|
29
|
+
export const MEDIA_DISPLAY_URL_SUCCESS = 'MEDIA_DISPLAY_URL_SUCCESS';
|
|
30
|
+
export const MEDIA_DISPLAY_URL_FAILURE = 'MEDIA_DISPLAY_URL_FAILURE';
|
|
31
|
+
export function createMediaLibrary(instance) {
|
|
32
|
+
const api = {
|
|
33
|
+
show: instance.show || (() => undefined),
|
|
34
|
+
hide: instance.hide || (() => undefined),
|
|
35
|
+
onClearControl: instance.onClearControl || (() => undefined),
|
|
36
|
+
onRemoveControl: instance.onRemoveControl || (() => undefined),
|
|
37
|
+
enableStandalone: instance.enableStandalone || (() => undefined)
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
type: MEDIA_LIBRARY_CREATE,
|
|
41
|
+
payload: api
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function clearMediaControl(id) {
|
|
45
|
+
return (_dispatch, getState) => {
|
|
46
|
+
const state = getState();
|
|
47
|
+
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
|
|
48
|
+
if (mediaLibrary) {
|
|
49
|
+
mediaLibrary.onClearControl({
|
|
50
|
+
id
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function removeMediaControl(id) {
|
|
56
|
+
return (_dispatch, getState) => {
|
|
57
|
+
const state = getState();
|
|
58
|
+
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
|
|
59
|
+
if (mediaLibrary) {
|
|
60
|
+
mediaLibrary.onRemoveControl({
|
|
61
|
+
id
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export function openMediaLibrary(payload = {}) {
|
|
67
|
+
return (dispatch, getState) => {
|
|
68
|
+
const state = getState();
|
|
69
|
+
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
|
|
70
|
+
if (mediaLibrary) {
|
|
71
|
+
const {
|
|
72
|
+
controlID: id,
|
|
73
|
+
value,
|
|
74
|
+
config = Map(),
|
|
75
|
+
allowMultiple,
|
|
76
|
+
forImage
|
|
77
|
+
} = payload;
|
|
78
|
+
mediaLibrary.show({
|
|
79
|
+
id,
|
|
80
|
+
value,
|
|
81
|
+
config: config.toJS(),
|
|
82
|
+
allowMultiple,
|
|
83
|
+
imagesOnly: forImage
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
dispatch(mediaLibraryOpened(payload));
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export function closeMediaLibrary() {
|
|
90
|
+
return (dispatch, getState) => {
|
|
91
|
+
const state = getState();
|
|
92
|
+
const mediaLibrary = state.mediaLibrary.get('externalLibrary');
|
|
93
|
+
if (mediaLibrary) {
|
|
94
|
+
mediaLibrary.hide();
|
|
95
|
+
}
|
|
96
|
+
dispatch(mediaLibraryClosed());
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export function insertMedia(mediaPath, field) {
|
|
100
|
+
return (dispatch, getState) => {
|
|
101
|
+
const state = getState();
|
|
102
|
+
const config = state.config;
|
|
103
|
+
const entry = state.entryDraft.get('entry');
|
|
104
|
+
const collectionName = state.entryDraft.getIn(['entry', 'collection']);
|
|
105
|
+
const collection = state.collections.get(collectionName);
|
|
106
|
+
if (Array.isArray(mediaPath)) {
|
|
107
|
+
mediaPath = mediaPath.map(path => selectMediaFilePublicPath(config, collection, path, entry, field));
|
|
108
|
+
} else {
|
|
109
|
+
mediaPath = selectMediaFilePublicPath(config, collection, mediaPath, entry, field);
|
|
110
|
+
}
|
|
111
|
+
dispatch(mediaInserted(mediaPath));
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export function removeInsertedMedia(controlID) {
|
|
115
|
+
return {
|
|
116
|
+
type: MEDIA_REMOVE_INSERTED,
|
|
117
|
+
payload: {
|
|
118
|
+
controlID
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export function loadMedia(opts = {}) {
|
|
123
|
+
const {
|
|
124
|
+
delay = 0,
|
|
125
|
+
query = '',
|
|
126
|
+
page = 1,
|
|
127
|
+
privateUpload
|
|
128
|
+
} = opts;
|
|
129
|
+
return async (dispatch, getState) => {
|
|
130
|
+
const state = getState();
|
|
131
|
+
const backend = currentBackend(state.config);
|
|
132
|
+
const integration = selectIntegration(state, null, 'assetStore');
|
|
133
|
+
if (integration) {
|
|
134
|
+
const provider = getIntegrationProvider(state.integrations, backend.getToken, integration);
|
|
135
|
+
dispatch(mediaLoading(page));
|
|
136
|
+
try {
|
|
137
|
+
const files = await provider.retrieve(query, page, privateUpload);
|
|
138
|
+
const mediaLoadedOpts = {
|
|
139
|
+
page,
|
|
140
|
+
canPaginate: true,
|
|
141
|
+
dynamicSearch: true,
|
|
142
|
+
dynamicSearchQuery: query,
|
|
143
|
+
privateUpload
|
|
144
|
+
};
|
|
145
|
+
return dispatch(mediaLoaded(files, mediaLoadedOpts));
|
|
146
|
+
} catch (error) {
|
|
147
|
+
return dispatch(mediaLoadFailed({
|
|
148
|
+
privateUpload
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
dispatch(mediaLoading(page));
|
|
153
|
+
function loadFunction() {
|
|
154
|
+
return backend.getMedia().then(files => dispatch(mediaLoaded(files))).catch(error => {
|
|
155
|
+
console.error(error);
|
|
156
|
+
if (error.status === 404) {
|
|
157
|
+
console.log('This 404 was expected and handled appropriately.');
|
|
158
|
+
dispatch(mediaLoaded([]));
|
|
159
|
+
} else {
|
|
160
|
+
dispatch(mediaLoadFailed());
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (delay > 0) {
|
|
165
|
+
return new Promise(resolve => {
|
|
166
|
+
setTimeout(() => resolve(loadFunction()), delay);
|
|
167
|
+
});
|
|
168
|
+
} else {
|
|
169
|
+
return loadFunction();
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function createMediaFileFromAsset({
|
|
174
|
+
id,
|
|
175
|
+
file,
|
|
176
|
+
assetProxy,
|
|
177
|
+
draft
|
|
178
|
+
}) {
|
|
179
|
+
const mediaFile = {
|
|
180
|
+
id,
|
|
181
|
+
name: basename(assetProxy.path),
|
|
182
|
+
displayURL: assetProxy.url,
|
|
183
|
+
draft,
|
|
184
|
+
file,
|
|
185
|
+
size: file.size,
|
|
186
|
+
url: assetProxy.url,
|
|
187
|
+
path: assetProxy.path,
|
|
188
|
+
field: assetProxy.field
|
|
189
|
+
};
|
|
190
|
+
return mediaFile;
|
|
191
|
+
}
|
|
192
|
+
export function persistMedia(file, opts = {}) {
|
|
193
|
+
const {
|
|
194
|
+
privateUpload,
|
|
195
|
+
field
|
|
196
|
+
} = opts;
|
|
197
|
+
return async (dispatch, getState) => {
|
|
198
|
+
const state = getState();
|
|
199
|
+
const backend = currentBackend(state.config);
|
|
200
|
+
const integration = selectIntegration(state, null, 'assetStore');
|
|
201
|
+
const files = selectMediaFiles(state, field);
|
|
202
|
+
const fileName = sanitizeSlug(file.name.toLowerCase(), state.config.slug);
|
|
203
|
+
const existingFile = files.find(existingFile => existingFile.name.toLowerCase() === fileName);
|
|
204
|
+
const editingDraft = selectEditingDraft(state.entryDraft);
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Check for existing files of the same name before persisting. If no asset
|
|
208
|
+
* store integration is used, files are being stored in Git, so we can
|
|
209
|
+
* expect file names to be unique. If an asset store is in use, file names
|
|
210
|
+
* may not be unique, so we forego this check.
|
|
211
|
+
*/
|
|
212
|
+
if (!integration && existingFile) {
|
|
213
|
+
if (!window.confirm(`${existingFile.name} already exists. Do you want to replace it?`)) {
|
|
214
|
+
return;
|
|
215
|
+
} else {
|
|
216
|
+
await dispatch(deleteMedia(existingFile, {
|
|
217
|
+
privateUpload
|
|
218
|
+
}));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (integration || !editingDraft) {
|
|
222
|
+
dispatch(mediaPersisting());
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
let assetProxy;
|
|
226
|
+
if (integration) {
|
|
227
|
+
try {
|
|
228
|
+
const provider = getIntegrationProvider(state.integrations, backend.getToken, integration);
|
|
229
|
+
const response = await provider.upload(file, privateUpload);
|
|
230
|
+
assetProxy = createAssetProxy({
|
|
231
|
+
url: response.asset.url,
|
|
232
|
+
path: response.asset.url
|
|
233
|
+
});
|
|
234
|
+
} catch (error) {
|
|
235
|
+
assetProxy = createAssetProxy({
|
|
236
|
+
file,
|
|
237
|
+
path: fileName
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
} else if (privateUpload) {
|
|
241
|
+
throw new Error('The Private Upload option is only available for Asset Store Integration');
|
|
242
|
+
} else {
|
|
243
|
+
const entry = state.entryDraft.get('entry');
|
|
244
|
+
const collection = state.collections.get(entry?.get('collection'));
|
|
245
|
+
const path = selectMediaFilePath(state.config, collection, entry, fileName, field);
|
|
246
|
+
assetProxy = createAssetProxy({
|
|
247
|
+
file,
|
|
248
|
+
path,
|
|
249
|
+
field
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
dispatch(addAsset(assetProxy));
|
|
253
|
+
let mediaFile;
|
|
254
|
+
if (integration) {
|
|
255
|
+
const id = await getBlobSHA(file);
|
|
256
|
+
// integration assets are persisted immediately, thus draft is false
|
|
257
|
+
mediaFile = createMediaFileFromAsset({
|
|
258
|
+
id,
|
|
259
|
+
file,
|
|
260
|
+
assetProxy,
|
|
261
|
+
draft: false
|
|
262
|
+
});
|
|
263
|
+
} else if (editingDraft) {
|
|
264
|
+
const id = await getBlobSHA(file);
|
|
265
|
+
mediaFile = createMediaFileFromAsset({
|
|
266
|
+
id,
|
|
267
|
+
file,
|
|
268
|
+
assetProxy,
|
|
269
|
+
draft: editingDraft
|
|
270
|
+
});
|
|
271
|
+
return dispatch(addDraftEntryMediaFile(mediaFile));
|
|
272
|
+
} else {
|
|
273
|
+
mediaFile = await backend.persistMedia(state.config, assetProxy);
|
|
274
|
+
}
|
|
275
|
+
return dispatch(mediaPersisted(mediaFile, {
|
|
276
|
+
privateUpload
|
|
277
|
+
}));
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error(error);
|
|
280
|
+
dispatch(addNotification({
|
|
281
|
+
message: `Failed to persist media: ${error}`,
|
|
282
|
+
type: 'error',
|
|
283
|
+
dismissAfter: 8000
|
|
284
|
+
}));
|
|
285
|
+
return dispatch(mediaPersistFailed({
|
|
286
|
+
privateUpload
|
|
287
|
+
}));
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
export function deleteMedia(file, opts = {}) {
|
|
292
|
+
const {
|
|
293
|
+
privateUpload
|
|
294
|
+
} = opts;
|
|
295
|
+
return async (dispatch, getState) => {
|
|
296
|
+
const state = getState();
|
|
297
|
+
const backend = currentBackend(state.config);
|
|
298
|
+
const integration = selectIntegration(state, null, 'assetStore');
|
|
299
|
+
if (integration) {
|
|
300
|
+
const provider = getIntegrationProvider(state.integrations, backend.getToken, integration);
|
|
301
|
+
dispatch(mediaDeleting());
|
|
302
|
+
try {
|
|
303
|
+
await provider.delete(file.id);
|
|
304
|
+
return dispatch(mediaDeleted(file, {
|
|
305
|
+
privateUpload
|
|
306
|
+
}));
|
|
307
|
+
} catch (error) {
|
|
308
|
+
console.error(error);
|
|
309
|
+
dispatch(addNotification({
|
|
310
|
+
message: `Failed to delete media: ${error.message}`,
|
|
311
|
+
type: 'error',
|
|
312
|
+
dismissAfter: 8000
|
|
313
|
+
}));
|
|
314
|
+
return dispatch(mediaDeleteFailed({
|
|
315
|
+
privateUpload
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
try {
|
|
320
|
+
if (file.draft) {
|
|
321
|
+
dispatch(removeAsset(file.path));
|
|
322
|
+
dispatch(removeDraftEntryMediaFile({
|
|
323
|
+
id: file.id
|
|
324
|
+
}));
|
|
325
|
+
} else {
|
|
326
|
+
const editingDraft = selectEditingDraft(state.entryDraft);
|
|
327
|
+
dispatch(mediaDeleting());
|
|
328
|
+
dispatch(removeAsset(file.path));
|
|
329
|
+
await backend.deleteMedia(state.config, file.path);
|
|
330
|
+
dispatch(mediaDeleted(file));
|
|
331
|
+
if (editingDraft) {
|
|
332
|
+
dispatch(removeDraftEntryMediaFile({
|
|
333
|
+
id: file.id
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
} catch (error) {
|
|
338
|
+
console.error(error);
|
|
339
|
+
dispatch(addNotification({
|
|
340
|
+
message: `Failed to delete media: ${error.message}`,
|
|
341
|
+
type: 'error',
|
|
342
|
+
dismissAfter: 8000
|
|
343
|
+
}));
|
|
344
|
+
return dispatch(mediaDeleteFailed());
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
export async function getMediaFile(state, path) {
|
|
349
|
+
const backend = currentBackend(state.config);
|
|
350
|
+
const {
|
|
351
|
+
url
|
|
352
|
+
} = await backend.getMediaFile(path);
|
|
353
|
+
return {
|
|
354
|
+
url
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
export function loadMediaDisplayURL(file) {
|
|
358
|
+
return async (dispatch, getState) => {
|
|
359
|
+
const {
|
|
360
|
+
displayURL,
|
|
361
|
+
id
|
|
362
|
+
} = file;
|
|
363
|
+
const state = getState();
|
|
364
|
+
const displayURLState = selectMediaDisplayURL(state, id);
|
|
365
|
+
if (!id || !displayURL || displayURLState.get('url') || displayURLState.get('isFetching') || displayURLState.get('err')) {
|
|
366
|
+
return Promise.resolve();
|
|
367
|
+
}
|
|
368
|
+
if (typeof displayURL === 'string') {
|
|
369
|
+
dispatch(mediaDisplayURLRequest(id));
|
|
370
|
+
dispatch(mediaDisplayURLSuccess(id, displayURL));
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
try {
|
|
374
|
+
const backend = currentBackend(state.config);
|
|
375
|
+
dispatch(mediaDisplayURLRequest(id));
|
|
376
|
+
const newURL = await backend.getMediaDisplayURL(displayURL);
|
|
377
|
+
if (newURL) {
|
|
378
|
+
dispatch(mediaDisplayURLSuccess(id, newURL));
|
|
379
|
+
} else {
|
|
380
|
+
throw new Error('No display URL was returned!');
|
|
381
|
+
}
|
|
382
|
+
} catch (err) {
|
|
383
|
+
console.error(err);
|
|
384
|
+
dispatch(mediaDisplayURLFailure(id, err));
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function mediaLibraryOpened(payload) {
|
|
389
|
+
return {
|
|
390
|
+
type: MEDIA_LIBRARY_OPEN,
|
|
391
|
+
payload
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function mediaLibraryClosed() {
|
|
395
|
+
return {
|
|
396
|
+
type: MEDIA_LIBRARY_CLOSE
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function mediaInserted(mediaPath) {
|
|
400
|
+
return {
|
|
401
|
+
type: MEDIA_INSERT,
|
|
402
|
+
payload: {
|
|
403
|
+
mediaPath
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
export function mediaLoading(page) {
|
|
408
|
+
return {
|
|
409
|
+
type: MEDIA_LOAD_REQUEST,
|
|
410
|
+
payload: {
|
|
411
|
+
page
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
export function mediaLoaded(files, opts = {}) {
|
|
416
|
+
return {
|
|
417
|
+
type: MEDIA_LOAD_SUCCESS,
|
|
418
|
+
payload: {
|
|
419
|
+
files,
|
|
420
|
+
...opts
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
export function mediaLoadFailed(opts = {}) {
|
|
425
|
+
const {
|
|
426
|
+
privateUpload
|
|
427
|
+
} = opts;
|
|
428
|
+
return {
|
|
429
|
+
type: MEDIA_LOAD_FAILURE,
|
|
430
|
+
payload: {
|
|
431
|
+
privateUpload
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
export function mediaPersisting() {
|
|
436
|
+
return {
|
|
437
|
+
type: MEDIA_PERSIST_REQUEST
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
export function mediaPersisted(file, opts = {}) {
|
|
441
|
+
const {
|
|
442
|
+
privateUpload
|
|
443
|
+
} = opts;
|
|
444
|
+
return {
|
|
445
|
+
type: MEDIA_PERSIST_SUCCESS,
|
|
446
|
+
payload: {
|
|
447
|
+
file,
|
|
448
|
+
privateUpload
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
export function mediaPersistFailed(opts = {}) {
|
|
453
|
+
const {
|
|
454
|
+
privateUpload
|
|
455
|
+
} = opts;
|
|
456
|
+
return {
|
|
457
|
+
type: MEDIA_PERSIST_FAILURE,
|
|
458
|
+
payload: {
|
|
459
|
+
privateUpload
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
export function mediaDeleting() {
|
|
464
|
+
return {
|
|
465
|
+
type: MEDIA_DELETE_REQUEST
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
export function mediaDeleted(file, opts = {}) {
|
|
469
|
+
const {
|
|
470
|
+
privateUpload
|
|
471
|
+
} = opts;
|
|
472
|
+
return {
|
|
473
|
+
type: MEDIA_DELETE_SUCCESS,
|
|
474
|
+
payload: {
|
|
475
|
+
file,
|
|
476
|
+
privateUpload
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
export function mediaDeleteFailed(opts = {}) {
|
|
481
|
+
const {
|
|
482
|
+
privateUpload
|
|
483
|
+
} = opts;
|
|
484
|
+
return {
|
|
485
|
+
type: MEDIA_DELETE_FAILURE,
|
|
486
|
+
payload: {
|
|
487
|
+
privateUpload
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
export function mediaDisplayURLRequest(key) {
|
|
492
|
+
return {
|
|
493
|
+
type: MEDIA_DISPLAY_URL_REQUEST,
|
|
494
|
+
payload: {
|
|
495
|
+
key
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
export function mediaDisplayURLSuccess(key, url) {
|
|
500
|
+
return {
|
|
501
|
+
type: MEDIA_DISPLAY_URL_SUCCESS,
|
|
502
|
+
payload: {
|
|
503
|
+
key,
|
|
504
|
+
url
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
export function mediaDisplayURLFailure(key, err) {
|
|
509
|
+
return {
|
|
510
|
+
type: MEDIA_DISPLAY_URL_FAILURE,
|
|
511
|
+
payload: {
|
|
512
|
+
key,
|
|
513
|
+
err
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
export async function waitForMediaLibraryToLoad(dispatch, state) {
|
|
518
|
+
if (state.mediaLibrary.get('isLoading') !== false && !state.mediaLibrary.get('externalLibrary')) {
|
|
519
|
+
await waitUntilWithTimeout(dispatch, resolve => ({
|
|
520
|
+
predicate: ({
|
|
521
|
+
type
|
|
522
|
+
}) => type === MEDIA_LOAD_SUCCESS || type === MEDIA_LOAD_FAILURE,
|
|
523
|
+
run: () => resolve()
|
|
524
|
+
}));
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
export async function getMediaDisplayURL(dispatch, state, file) {
|
|
528
|
+
const displayURLState = selectMediaDisplayURL(state, file.id);
|
|
529
|
+
let url;
|
|
530
|
+
if (displayURLState.get('url')) {
|
|
531
|
+
// url was already loaded
|
|
532
|
+
url = displayURLState.get('url');
|
|
533
|
+
} else if (displayURLState.get('err')) {
|
|
534
|
+
// url loading had an error
|
|
535
|
+
url = null;
|
|
536
|
+
} else {
|
|
537
|
+
const key = file.id;
|
|
538
|
+
const promise = waitUntilWithTimeout(dispatch, resolve => ({
|
|
539
|
+
predicate: ({
|
|
540
|
+
type,
|
|
541
|
+
payload
|
|
542
|
+
}) => (type === MEDIA_DISPLAY_URL_SUCCESS || type === MEDIA_DISPLAY_URL_FAILURE) && payload.key === key,
|
|
543
|
+
run: (_dispatch, _getState, action) => resolve(action.payload.url)
|
|
544
|
+
}));
|
|
545
|
+
if (!displayURLState.get('isFetching')) {
|
|
546
|
+
// load display url
|
|
547
|
+
dispatch(loadMediaDisplayURL(file));
|
|
548
|
+
}
|
|
549
|
+
url = (await promise) ?? null;
|
|
550
|
+
}
|
|
551
|
+
return url;
|
|
552
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const NOTIFICATION_SEND = 'NOTIFICATION_SEND';
|
|
2
|
+
export const NOTIFICATION_DISMISS = 'NOTIFICATION_DISMISS';
|
|
3
|
+
export const NOTIFICATIONS_CLEAR = 'NOTIFICATION_CLEAR';
|
|
4
|
+
function addNotification(notification) {
|
|
5
|
+
return {
|
|
6
|
+
type: NOTIFICATION_SEND,
|
|
7
|
+
payload: notification
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function dismissNotification(id) {
|
|
11
|
+
return {
|
|
12
|
+
type: NOTIFICATION_DISMISS,
|
|
13
|
+
id
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function clearNotifications() {
|
|
17
|
+
return {
|
|
18
|
+
type: NOTIFICATIONS_CLEAR
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export { addNotification, dismissNotification, clearNotifications };
|