174 lines
5.5 KiB
JavaScript
174 lines
5.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';
|
|
import workspaceSvc from './workspaceSvc';
|
|
import badgeSvc from './badgeSvc';
|
|
|
|
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}`);
|
|
};
|
|
|
|
// git 相关的 providerId
|
|
const gitProviderIds = ['gitea', 'gitee', 'github', 'gitlab'];
|
|
|
|
const publish = async (publishLocation, commitMessage) => {
|
|
const { fileId } = publishLocation;
|
|
const template = store.getters['data/allTemplatesById'][publishLocation.templateId];
|
|
const html = await exportSvc.applyTemplate(fileId, template);
|
|
const content = await localDbSvc.loadItem(`${fileId}/content`);
|
|
const file = store.state.file.itemsById[fileId];
|
|
const properties = utils.computeProperties(content.properties);
|
|
const provider = providerRegistry.providersById[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, commitMessage);
|
|
};
|
|
|
|
const publishFile = async (fileId) => {
|
|
let counter = 0;
|
|
await loadContent(fileId);
|
|
const publishLocations = [
|
|
...store.getters['publishLocation/filteredGroupedByFileId'][fileId] || [],
|
|
];
|
|
try {
|
|
// 查询是否包含git provider 包含则需要填入提交信息
|
|
const gitLocations = publishLocations.filter(it => gitProviderIds.indexOf(it.providerId) > -1);
|
|
let commitMsg = '';
|
|
if (gitLocations.length) {
|
|
try {
|
|
const { commitMessage } = await store.dispatch('modal/open', { type: 'commitMessage' });
|
|
commitMsg = commitMessage;
|
|
} catch (e) {
|
|
return;
|
|
}
|
|
}
|
|
await utils.awaitSequence(publishLocations, async (publishLocation) => {
|
|
await store.dispatch('queue/doWithLocation', {
|
|
location: publishLocation,
|
|
action: async () => {
|
|
const publishLocationToStore = await publish(publishLocation, commitMsg);
|
|
try {
|
|
// Replace publish location if modified
|
|
if (utils.serializeObject(publishLocation) !==
|
|
utils.serializeObject(publishLocationToStore)
|
|
) {
|
|
store.commit('publishLocation/patchItem', publishLocationToStore);
|
|
workspaceSvc.ensureUniqueLocations();
|
|
}
|
|
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.itemsById[fileId];
|
|
store.dispatch('notification/info', `"${file.name}"已发布到${counter}个位置。`);
|
|
} finally {
|
|
await localDbSvc.unloadContents();
|
|
}
|
|
};
|
|
|
|
const requestPublish = () => {
|
|
// No publish in light mode
|
|
if (store.state.light) {
|
|
return;
|
|
}
|
|
|
|
store.dispatch('queue/enqueuePublishRequest', async () => {
|
|
let intervalId;
|
|
const attempt = async () => {
|
|
// Only start publishing when these conditions are met
|
|
if (networkSvc.isUserActive()) {
|
|
clearInterval(intervalId);
|
|
if (!hasCurrentFilePublishLocations()) {
|
|
// Cancel publish
|
|
throw new Error('Publish not possible.');
|
|
}
|
|
await publishFile(store.getters['file/current'].id);
|
|
badgeSvc.addBadge('triggerPublish');
|
|
}
|
|
};
|
|
intervalId = utils.setInterval(() => attempt(), 1000);
|
|
return attempt();
|
|
});
|
|
};
|
|
|
|
const createPublishLocation = (publishLocation, featureId) => {
|
|
const currentFile = store.getters['file/current'];
|
|
publishLocation.fileId = currentFile.id;
|
|
store.dispatch(
|
|
'queue/enqueue',
|
|
async () => {
|
|
let commitMsg = '';
|
|
if (gitProviderIds.indexOf(publishLocation.providerId) > -1) {
|
|
try {
|
|
const { commitMessage } = await store.dispatch('modal/open', {
|
|
type: 'commitMessage',
|
|
name: currentFile.name,
|
|
});
|
|
commitMsg = commitMessage;
|
|
} catch (e) {
|
|
return;
|
|
}
|
|
}
|
|
const publishLocationToStore = await publish(publishLocation, commitMsg);
|
|
workspaceSvc.addPublishLocation(publishLocationToStore);
|
|
store.dispatch('notification/info', `添加了一个新的发布位置 "${currentFile.name}".`);
|
|
if (featureId) {
|
|
badgeSvc.addBadge(featureId);
|
|
}
|
|
},
|
|
);
|
|
};
|
|
|
|
export default {
|
|
requestPublish,
|
|
createPublishLocation,
|
|
};
|