144 lines
4.5 KiB
JavaScript
144 lines
4.5 KiB
JavaScript
import localDbSvc from './localDbSvc';
|
|
import store from '../store';
|
|
import utils from './utils';
|
|
import networkSvc from './networkSvc';
|
|
import exportSvc from './exportSvc';
|
|
import providerRegistry from './providers/common/providerRegistry';
|
|
|
|
const hasCurrentFilePublishLocations = () => !!store.getters['publishLocation/current'].length;
|
|
|
|
const loader = type => fileId => localDbSvc.loadItem(`${fileId}/${type}`)
|
|
// Item does not exist, create it
|
|
.catch(() => store.commit(`${type}/setItem`, {
|
|
id: `${fileId}/${type}`,
|
|
}));
|
|
const loadContent = loader('content');
|
|
|
|
const ensureArray = (value) => {
|
|
if (!value) {
|
|
return [];
|
|
}
|
|
if (!Array.isArray(value)) {
|
|
return `${value}`.trim().split(/\s*,\s*/);
|
|
}
|
|
return value;
|
|
};
|
|
|
|
const ensureString = (value, defaultValue) => {
|
|
if (!value) {
|
|
return defaultValue;
|
|
}
|
|
return `${value}`;
|
|
};
|
|
|
|
const ensureDate = (value, defaultValue) => {
|
|
if (!value) {
|
|
return defaultValue;
|
|
}
|
|
return new Date(`${value}`);
|
|
};
|
|
|
|
const publish = async (publishLocation) => {
|
|
const { fileId } = publishLocation;
|
|
const template = store.getters['data/allTemplates'][publishLocation.templateId];
|
|
const html = await exportSvc.applyTemplate(fileId, template);
|
|
const content = await localDbSvc.loadItem(`${fileId}/content`);
|
|
const file = store.state.file.itemMap[fileId];
|
|
const properties = utils.computeProperties(content.properties);
|
|
const provider = providerRegistry.providers[publishLocation.providerId];
|
|
const token = provider.getToken(publishLocation);
|
|
const metadata = {
|
|
title: ensureString(properties.title, file.name),
|
|
author: ensureString(properties.author),
|
|
tags: ensureArray(properties.tags),
|
|
categories: ensureArray(properties.categories),
|
|
excerpt: ensureString(properties.excerpt),
|
|
featuredImage: ensureString(properties.featuredImage),
|
|
status: ensureString(properties.status),
|
|
date: ensureDate(properties.date, new Date()),
|
|
};
|
|
return provider.publish(token, html, metadata, publishLocation);
|
|
};
|
|
|
|
const publishFile = async (fileId) => {
|
|
let counter = 0;
|
|
await loadContent(fileId);
|
|
const publishLocations = [
|
|
...store.getters['publishLocation/filteredGroupedByFileId'][fileId] || [],
|
|
];
|
|
try {
|
|
await utils.awaitSequence(publishLocations, async (publishLocation) => {
|
|
await store.dispatch('queue/doWithLocation', {
|
|
location: publishLocation,
|
|
action: async () => {
|
|
const publishLocationToStore = await publish(publishLocation);
|
|
try {
|
|
// Replace publish location if modified
|
|
if (utils.serializeObject(publishLocation) !==
|
|
utils.serializeObject(publishLocationToStore)
|
|
) {
|
|
store.commit('publishLocation/patchItem', publishLocationToStore);
|
|
}
|
|
counter += 1;
|
|
} catch (err) {
|
|
if (store.state.offline) {
|
|
throw err;
|
|
}
|
|
console.error(err); // eslint-disable-line no-console
|
|
store.dispatch('notification/error', err);
|
|
}
|
|
},
|
|
});
|
|
});
|
|
const file = store.state.file.itemMap[fileId];
|
|
store.dispatch('notification/info', `"${file.name}" was published to ${counter} location(s).`);
|
|
} finally {
|
|
await localDbSvc.unloadContents();
|
|
}
|
|
};
|
|
|
|
const requestPublish = () => {
|
|
// No publish in light mode
|
|
if (store.state.light) {
|
|
return;
|
|
}
|
|
|
|
store.dispatch('queue/enqueuePublishRequest', () => new Promise((resolve, reject) => {
|
|
let intervalId;
|
|
const attempt = () => {
|
|
// Only start publishing when these conditions are met
|
|
if (networkSvc.isUserActive()) {
|
|
clearInterval(intervalId);
|
|
if (!hasCurrentFilePublishLocations()) {
|
|
// Cancel sync
|
|
reject(new Error('Publish not possible.'));
|
|
return;
|
|
}
|
|
publishFile(store.getters['file/current'].id)
|
|
.then(resolve, reject);
|
|
}
|
|
};
|
|
intervalId = utils.setInterval(() => attempt(), 1000);
|
|
attempt();
|
|
}));
|
|
};
|
|
|
|
const createPublishLocation = (publishLocation) => {
|
|
publishLocation.id = utils.uid();
|
|
const currentFile = store.getters['file/current'];
|
|
publishLocation.fileId = currentFile.id;
|
|
store.dispatch(
|
|
'queue/enqueue',
|
|
async () => {
|
|
const publishLocationToStore = await publish(publishLocation);
|
|
store.commit('publishLocation/setItem', publishLocationToStore);
|
|
store.dispatch('notification/info', `A new publication location was added to "${currentFile.name}".`);
|
|
},
|
|
);
|
|
};
|
|
|
|
export default {
|
|
requestPublish,
|
|
createPublishLocation,
|
|
};
|