Preparing for github file persistence
This commit is contained in:
parent
6f0f13ad40
commit
18ad041d96
@ -73,6 +73,7 @@
|
|||||||
"draft-js-export-markdown": "^0.2.0",
|
"draft-js-export-markdown": "^0.2.0",
|
||||||
"draft-js-import-markdown": "^0.1.6",
|
"draft-js-import-markdown": "^0.1.6",
|
||||||
"fuzzy": "^0.1.1",
|
"fuzzy": "^0.1.1",
|
||||||
|
"js-base64": "^2.1.9",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"localforage": "^1.4.2",
|
"localforage": "^1.4.2",
|
||||||
"lodash": "^4.13.1"
|
"lodash": "^4.13.1"
|
||||||
|
@ -11,7 +11,7 @@ export const ENTRIES_REQUEST = 'ENTRIES_REQUEST';
|
|||||||
export const ENTRIES_SUCCESS = 'ENTRIES_SUCCESS';
|
export const ENTRIES_SUCCESS = 'ENTRIES_SUCCESS';
|
||||||
export const ENTRIES_FAILURE = 'ENTRIES_FAILURE';
|
export const ENTRIES_FAILURE = 'ENTRIES_FAILURE';
|
||||||
|
|
||||||
export const DRAFT_CREATE = 'DRAFT_CREATE';
|
export const DRAFT_CREATE_FROM_ENTRY = 'DRAFT_CREATE_FROM_ENTRY';
|
||||||
export const DRAFT_DISCARD = 'DRAFT_DISCARD';
|
export const DRAFT_DISCARD = 'DRAFT_DISCARD';
|
||||||
export const DRAFT_CHANGE = 'DRAFT_CHANGE';
|
export const DRAFT_CHANGE = 'DRAFT_CHANGE';
|
||||||
|
|
||||||
@ -104,9 +104,9 @@ function entryPersistFail(collection, entry, error) {
|
|||||||
/*
|
/*
|
||||||
* Exported simple Action Creators
|
* Exported simple Action Creators
|
||||||
*/
|
*/
|
||||||
export function createDraft(entry) {
|
export function createDraftFromEntry(entry) {
|
||||||
return {
|
return {
|
||||||
type: DRAFT_CREATE,
|
type: DRAFT_CREATE_FROM_ENTRY,
|
||||||
payload: entry
|
payload: entry
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -152,12 +152,12 @@ export function loadEntries(collection) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function persist(collection, entry, mediaFiles) {
|
export function persistEntry(collection, entry, mediaFiles) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const backend = currentBackend(state.config);
|
const backend = currentBackend(state.config);
|
||||||
dispatch(entryPersisting(collection, entry));
|
dispatch(entryPersisting(collection, entry));
|
||||||
backend.persist(collection, entry, mediaFiles).then(
|
backend.persistEntry(collection, entry, mediaFiles).then(
|
||||||
({persistedEntry, persistedMediaFiles}) => {
|
({persistedEntry, persistedMediaFiles}) => {
|
||||||
dispatch(entryPersisted(persistedEntry, persistedMediaFiles));
|
dispatch(entryPersisted(persistedEntry, persistedMediaFiles));
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,6 @@ export function addMedia(mediaProxy) {
|
|||||||
return { type: ADD_MEDIA, payload: mediaProxy };
|
return { type: ADD_MEDIA, payload: mediaProxy };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeMedia(uri) {
|
export function removeMedia(path) {
|
||||||
return { type: REMOVE_MEDIA, payload: uri };
|
return { type: REMOVE_MEDIA, payload: path };
|
||||||
}
|
}
|
||||||
|
@ -67,14 +67,21 @@ class Backend {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
persist(collection, entryDraft) {
|
persistEntry(collection, entryDraft) {
|
||||||
const entryData = entryDraft.getIn(['entry', 'data']).toObject();
|
const entryData = entryDraft.getIn(['entry', 'data']).toObject();
|
||||||
const entryObj = {
|
const entryObj = {
|
||||||
path: entryDraft.getIn(['entry', 'path']),
|
path: entryDraft.getIn(['entry', 'path']),
|
||||||
slug: entryDraft.getIn(['entry', 'slug']),
|
slug: entryDraft.getIn(['entry', 'slug']),
|
||||||
raw: this.entryToRaw(collection, entryData)
|
raw: this.entryToRaw(collection, entryData)
|
||||||
};
|
};
|
||||||
return this.implementation.persist(collection, entryObj, entryDraft.get('mediaFiles').toJS()).then(
|
|
||||||
|
const commitMessage = (entryDraft.getIn(['entry', 'newRecord']) ? 'Created ' : 'Updated ') +
|
||||||
|
collection.get('label') + ' “' +
|
||||||
|
entryDraft.getIn(['entry', 'data', 'title']) + '”';
|
||||||
|
|
||||||
|
|
||||||
|
return this.implementation.persistEntry(collection, entryObj, entryDraft.get('mediaFiles').toJS(), { commitMessage })
|
||||||
|
.then(
|
||||||
(response) => ({
|
(response) => ({
|
||||||
persistedEntry: this.entryWithFormat(collection)(response.persistedEntry),
|
persistedEntry: this.entryWithFormat(collection)(response.persistedEntry),
|
||||||
persistedMediaFiles:response.persistedMediaFiles
|
persistedMediaFiles:response.persistedMediaFiles
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import LocalForage from 'localforage';
|
import LocalForage from 'localforage';
|
||||||
|
import MediaProxy from '../../valueObjects/MediaProxy';
|
||||||
import AuthenticationPage from './AuthenticationPage';
|
import AuthenticationPage from './AuthenticationPage';
|
||||||
|
import { Base64 } from 'js-base64';
|
||||||
|
|
||||||
const API_ROOT = 'https://api.github.com';
|
const API_ROOT = 'https://api.github.com';
|
||||||
|
|
||||||
@ -40,6 +42,43 @@ class API {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
persistFiles(collection, entry, mediaFiles, options) {
|
||||||
|
let filename, part, parts, subtree;
|
||||||
|
const fileTree = {};
|
||||||
|
const files = [];
|
||||||
|
|
||||||
|
mediaFiles.concat(entry).forEach((file) => {
|
||||||
|
if (file.uploaded) { return; }
|
||||||
|
files.push(this.uploadBlob(file));
|
||||||
|
parts = file.path.split('/').filter((part) => part);
|
||||||
|
filename = parts.pop();
|
||||||
|
subtree = fileTree;
|
||||||
|
while (part = parts.shift()) {
|
||||||
|
subtree[part] = subtree[part] || {};
|
||||||
|
subtree = subtree[part];
|
||||||
|
}
|
||||||
|
subtree[filename] = file;
|
||||||
|
file.file = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return Promise.all(files)
|
||||||
|
.then(() => this.getBranch())
|
||||||
|
.then((branchData) => {
|
||||||
|
return this.updateTree(branchData.commit.sha, '/', fileTree);
|
||||||
|
})
|
||||||
|
.then((changeTree) => {
|
||||||
|
return this.request(`${this.repoURL}/git/commits`, {
|
||||||
|
type: 'POST',
|
||||||
|
data: JSON.stringify({ message: options.message, tree: changeTree.sha, parents: [changeTree.parentSha] })
|
||||||
|
});
|
||||||
|
}).then((response) => {
|
||||||
|
return this.request(`${this.repoURL}/git/refs/heads/${this.branch}`, {
|
||||||
|
type: 'PATCH',
|
||||||
|
data: JSON.stringify({ sha: response.sha })
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
requestHeaders(headers = {}) {
|
requestHeaders(headers = {}) {
|
||||||
return {
|
return {
|
||||||
Authorization: `token ${this.token}`,
|
Authorization: `token ${this.token}`,
|
||||||
@ -68,6 +107,78 @@ class API {
|
|||||||
return response.text();
|
return response.text();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBranch() {
|
||||||
|
return this.request(`${this.repoURL}/branches/${this.branch}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTree(sha) {
|
||||||
|
return sha ? this.request(`${this.repoURL}/git/trees/${sha}`) : Promise.resolve({ tree: [] });
|
||||||
|
}
|
||||||
|
|
||||||
|
toBase64(str) {
|
||||||
|
return Promise.resolve(
|
||||||
|
Base64.encode(str)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadBlob(item) {
|
||||||
|
const content = item instanceof MediaProxy ? item.toBase64() : this.toBase64(item.raw);
|
||||||
|
|
||||||
|
return content.then((contentBase64) => {
|
||||||
|
return this.request(`${this.repoURL}/git/blobs`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
content: contentBase64,
|
||||||
|
encoding: 'base64'
|
||||||
|
})
|
||||||
|
}).then((response) => {
|
||||||
|
item.sha = response.sha;
|
||||||
|
item.uploaded = true;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTree(sha, path, fileTree) {
|
||||||
|
return this.getTree(sha)
|
||||||
|
.then((tree) => {
|
||||||
|
var obj, filename, fileOrDir;
|
||||||
|
var updates = [];
|
||||||
|
var added = {};
|
||||||
|
|
||||||
|
for (var i = 0, len = tree.tree.length; i < len; i++) {
|
||||||
|
obj = tree.tree[i];
|
||||||
|
if (fileOrDir = fileTree[obj.path]) {
|
||||||
|
added[obj.path] = true;
|
||||||
|
if (fileOrDir.file) {
|
||||||
|
updates.push({ path: obj.path, mode: obj.mode, type: obj.type, sha: fileOrDir.sha });
|
||||||
|
} else {
|
||||||
|
updates.push(this.updateTree(obj.sha, obj.path, fileOrDir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (filename in fileTree) {
|
||||||
|
fileOrDir = fileTree[filename];
|
||||||
|
if (added[filename]) { continue; }
|
||||||
|
updates.push(
|
||||||
|
fileOrDir.file ?
|
||||||
|
{ path: filename, mode: '100644', type: 'blob', sha: fileOrDir.sha } :
|
||||||
|
this.updateTree(null, filename, fileOrDir)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Promise.all(updates)
|
||||||
|
.then((updates) => {
|
||||||
|
return this.request(`${this.repoURL}/git/trees`, {
|
||||||
|
type: 'POST',
|
||||||
|
data: JSON.stringify({ base_tree: sha, tree: updates })
|
||||||
|
});
|
||||||
|
}).then((response) => {
|
||||||
|
return { path: path, mode: '040000', type: 'tree', sha: response.sha, parentSha: sha };
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class GitHub {
|
export default class GitHub {
|
||||||
@ -115,4 +226,8 @@ export default class GitHub {
|
|||||||
response.entries.filter((entry) => entry.slug === slug)[0]
|
response.entries.filter((entry) => entry.slug === slug)[0]
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
persistEntry(collection, entry, mediaFiles = []) {
|
||||||
|
return this.api.persistFiles(collection, entry, mediaFiles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,10 @@ export default class TestRepo {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
persist(collection, entry, mediaFiles = []) {
|
persistEntry(collection, entry, mediaFiles = []) {
|
||||||
const folder = collection.get('folder');
|
const folder = entry.path.substring(0, entry.path.lastIndexOf('/'));
|
||||||
const fileName = entry.path.substring(entry.path.lastIndexOf('/') + 1);
|
const fileName = entry.path.substring(entry.path.lastIndexOf('/') + 1);
|
||||||
window.repoFiles[folder][fileName]['content'] = entry.raw;
|
window.repoFiles[folder][fileName]['content'] = entry.raw;
|
||||||
return Promise.resolve({persistedEntry:entry, persistedMediaFiles:[]});
|
return Promise.resolve({ persistedEntry:entry, persistedMediaFiles:[] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ export default class ImageControl extends React.Component {
|
|||||||
if (file) {
|
if (file) {
|
||||||
const mediaProxy = new MediaProxy(file.name, file);
|
const mediaProxy = new MediaProxy(file.name, file);
|
||||||
this.props.onAddMedia(mediaProxy);
|
this.props.onAddMedia(mediaProxy);
|
||||||
this.props.onChange(mediaProxy.uri);
|
this.props.onChange(mediaProxy.path);
|
||||||
} else {
|
} else {
|
||||||
this.props.onChange(null);
|
this.props.onChange(null);
|
||||||
}
|
}
|
||||||
@ -63,7 +63,7 @@ export default class ImageControl extends React.Component {
|
|||||||
renderImageName() {
|
renderImageName() {
|
||||||
if (!this.props.value) return null;
|
if (!this.props.value) return null;
|
||||||
if (this.value instanceof MediaProxy) {
|
if (this.value instanceof MediaProxy) {
|
||||||
return truncateMiddle(this.props.value.uri, MAX_DISPLAY_LENGTH);
|
return truncateMiddle(this.props.value.path, MAX_DISPLAY_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
return truncateMiddle(this.props.value, MAX_DISPLAY_LENGTH);
|
return truncateMiddle(this.props.value, MAX_DISPLAY_LENGTH);
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
loadEntry,
|
loadEntry,
|
||||||
createDraft,
|
createDraftFromEntry,
|
||||||
discardDraft,
|
discardDraft,
|
||||||
changeDraft,
|
changeDraft,
|
||||||
persist
|
persistEntry
|
||||||
} from '../actions/entries';
|
} from '../actions/entries';
|
||||||
import { addMedia, removeMedia } from '../actions/media';
|
import { addMedia, removeMedia } from '../actions/media';
|
||||||
import { selectEntry, getMedia } from '../reducers';
|
import { selectEntry, getMedia } from '../reducers';
|
||||||
@ -16,18 +16,18 @@ class EntryPage extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.props.loadEntry(props.collection, props.slug);
|
this.props.loadEntry(props.collection, props.slug);
|
||||||
this.handlePersist = this.handlePersist.bind(this);
|
this.handlePersistEntry = this.handlePersistEntry.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.props.entry) {
|
if (this.props.entry) {
|
||||||
this.props.createDraft(this.props.entry);
|
this.props.createDraftFromEntry(this.props.entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
if (this.props.entry !== nextProps.entry && !nextProps.entry.get('isFetching')) {
|
if (this.props.entry !== nextProps.entry && !nextProps.entry.get('isFetching')) {
|
||||||
this.props.createDraft(nextProps.entry);
|
this.props.createDraftFromEntry(nextProps.entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,8 +35,8 @@ class EntryPage extends React.Component {
|
|||||||
this.props.discardDraft();
|
this.props.discardDraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePersist() {
|
handlePersistEntry() {
|
||||||
this.props.persist(this.props.collection, this.props.entryDraft);
|
this.props.persistEntry(this.props.collection, this.props.entryDraft);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -56,7 +56,7 @@ class EntryPage extends React.Component {
|
|||||||
onChange={changeDraft}
|
onChange={changeDraft}
|
||||||
onAddMedia={addMedia}
|
onAddMedia={addMedia}
|
||||||
onRemoveMedia={removeMedia}
|
onRemoveMedia={removeMedia}
|
||||||
onPersist={this.handlePersist}
|
onPersist={this.handlePersistEntry}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -67,12 +67,12 @@ EntryPage.propTypes = {
|
|||||||
boundGetMedia: PropTypes.func.isRequired,
|
boundGetMedia: PropTypes.func.isRequired,
|
||||||
changeDraft: PropTypes.func.isRequired,
|
changeDraft: PropTypes.func.isRequired,
|
||||||
collection: ImmutablePropTypes.map.isRequired,
|
collection: ImmutablePropTypes.map.isRequired,
|
||||||
createDraft: PropTypes.func.isRequired,
|
createDraftFromEntry: PropTypes.func.isRequired,
|
||||||
discardDraft: PropTypes.func.isRequired,
|
discardDraft: PropTypes.func.isRequired,
|
||||||
entry: ImmutablePropTypes.map.isRequired,
|
entry: ImmutablePropTypes.map.isRequired,
|
||||||
entryDraft: ImmutablePropTypes.map.isRequired,
|
entryDraft: ImmutablePropTypes.map.isRequired,
|
||||||
loadEntry: PropTypes.func.isRequired,
|
loadEntry: PropTypes.func.isRequired,
|
||||||
persist: PropTypes.func.isRequired,
|
persistEntry: PropTypes.func.isRequired,
|
||||||
removeMedia: PropTypes.func.isRequired,
|
removeMedia: PropTypes.func.isRequired,
|
||||||
slug: PropTypes.string.isRequired,
|
slug: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
@ -93,8 +93,8 @@ export default connect(
|
|||||||
addMedia,
|
addMedia,
|
||||||
removeMedia,
|
removeMedia,
|
||||||
loadEntry,
|
loadEntry,
|
||||||
createDraft,
|
createDraftFromEntry,
|
||||||
discardDraft,
|
discardDraft,
|
||||||
persist
|
persistEntry
|
||||||
}
|
}
|
||||||
)(EntryPage);
|
)(EntryPage);
|
||||||
|
@ -19,7 +19,7 @@ const ImageType = new yaml.Type('image', {
|
|||||||
kind: 'scalar',
|
kind: 'scalar',
|
||||||
instanceOf: MediaProxy,
|
instanceOf: MediaProxy,
|
||||||
represent: function(value) {
|
represent: function(value) {
|
||||||
return `${value.uri}`;
|
return `${value.path}`;
|
||||||
},
|
},
|
||||||
resolve: function(value) {
|
resolve: function(value) {
|
||||||
if (value === null) return false;
|
if (value === null) return false;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Map, List } from 'immutable';
|
import { Map, List } from 'immutable';
|
||||||
import { DRAFT_CREATE, DRAFT_DISCARD, DRAFT_CHANGE } from '../actions/entries';
|
import { DRAFT_CREATE_FROM_ENTRY, DRAFT_DISCARD, DRAFT_CHANGE } from '../actions/entries';
|
||||||
import { ADD_MEDIA, REMOVE_MEDIA } from '../actions/media';
|
import { ADD_MEDIA, REMOVE_MEDIA } from '../actions/media';
|
||||||
|
|
||||||
const initialState = Map({ entry: Map(), mediaFiles: List() });
|
const initialState = Map({ entry: Map(), mediaFiles: List() });
|
||||||
|
|
||||||
const entryDraft = (state = Map(), action) => {
|
const entryDraft = (state = Map(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case DRAFT_CREATE:
|
case DRAFT_CREATE_FROM_ENTRY:
|
||||||
if (!action.payload) {
|
if (!action.payload) {
|
||||||
// New entry
|
// New entry
|
||||||
return initialState;
|
return initialState;
|
||||||
@ -14,6 +14,7 @@ const entryDraft = (state = Map(), action) => {
|
|||||||
// Existing Entry
|
// Existing Entry
|
||||||
return state.withMutations((state) => {
|
return state.withMutations((state) => {
|
||||||
state.set('entry', action.payload);
|
state.set('entry', action.payload);
|
||||||
|
state.setIn(['entry', 'newRecord'], false);
|
||||||
state.set('mediaFiles', List());
|
state.set('mediaFiles', List());
|
||||||
});
|
});
|
||||||
case DRAFT_DISCARD:
|
case DRAFT_DISCARD:
|
||||||
@ -22,9 +23,9 @@ const entryDraft = (state = Map(), action) => {
|
|||||||
return state.set('entry', action.payload);
|
return state.set('entry', action.payload);
|
||||||
|
|
||||||
case ADD_MEDIA:
|
case ADD_MEDIA:
|
||||||
return state.update('mediaFiles', (list) => list.push(action.payload.uri));
|
return state.update('mediaFiles', (list) => list.push(action.payload.path));
|
||||||
case REMOVE_MEDIA:
|
case REMOVE_MEDIA:
|
||||||
return state.update('mediaFiles', (list) => list.filterNot((uri) => uri === action.payload));
|
return state.update('mediaFiles', (list) => list.filterNot((path) => path === action.payload));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
@ -23,5 +23,5 @@ export const selectEntry = (state, collection, slug) =>
|
|||||||
export const selectEntries = (state, collection) =>
|
export const selectEntries = (state, collection) =>
|
||||||
fromEntries.selectEntries(state.entries, collection);
|
fromEntries.selectEntries(state.entries, collection);
|
||||||
|
|
||||||
export const getMedia = (state, uri) =>
|
export const getMedia = (state, path) =>
|
||||||
fromMedias.getMedia(state.medias, uri);
|
fromMedias.getMedia(state.medias, path);
|
||||||
|
@ -6,12 +6,12 @@ import MediaProxy from '../valueObjects/MediaProxy';
|
|||||||
const medias = (state = Map(), action) => {
|
const medias = (state = Map(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ADD_MEDIA:
|
case ADD_MEDIA:
|
||||||
return state.set(action.payload.uri, action.payload);
|
return state.set(action.payload.path, action.payload);
|
||||||
case REMOVE_MEDIA:
|
case REMOVE_MEDIA:
|
||||||
return state.delete(action.payload);
|
return state.delete(action.payload);
|
||||||
case ENTRY_PERSIST_SUCCESS:
|
case ENTRY_PERSIST_SUCCESS:
|
||||||
return state.map((media, uri) => {
|
return state.map((media, path) => {
|
||||||
if (action.payload.persistedMediaFiles.indexOf(uri) > -1) media.uploaded = true;
|
if (action.payload.persistedMediaFiles.indexOf(path) > -1) media.uploaded = true;
|
||||||
return media;
|
return media;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -22,10 +22,10 @@ const medias = (state = Map(), action) => {
|
|||||||
|
|
||||||
export default medias;
|
export default medias;
|
||||||
|
|
||||||
export const getMedia = (state, uri) => {
|
export const getMedia = (state, path) => {
|
||||||
if (state.has(uri)) {
|
if (state.has(path)) {
|
||||||
return state.get(uri);
|
return state.get(path);
|
||||||
} else {
|
} else {
|
||||||
return new MediaProxy(uri, null, true);
|
return new MediaProxy(path, null, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -7,8 +7,21 @@ export default function MediaProxy(value, file, uploaded = false) {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.uploaded = uploaded;
|
this.uploaded = uploaded;
|
||||||
this.uri = config.media_folder && !uploaded ? config.media_folder + '/' + value : value;
|
this.sha = null;
|
||||||
this.toString = function() {
|
this.path = config.media_folder && !uploaded ? config.media_folder + '/' + value : value;
|
||||||
return this.uploaded ? this.uri : window.URL.createObjectURL(this.file, { oneTimeOnly: true });
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaProxy.prototype.toString = function() {
|
||||||
|
return this.uploaded ? this.path : window.URL.createObjectURL(this.file, { oneTimeOnly: true });
|
||||||
|
};
|
||||||
|
|
||||||
|
MediaProxy.prototype.toBase64 = function() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const fr = new FileReader();
|
||||||
|
fr.onload = (readerEvt) => {
|
||||||
|
const binaryString = readerEvt.target.result;
|
||||||
|
resolve(btoa(binaryString));
|
||||||
|
};
|
||||||
|
fr.readAsDataURL(this.file);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user