仓库支持关闭自动同步

This commit is contained in:
xiaoqi.cxq 2022-09-23 19:33:25 +08:00
parent f020cb887b
commit 398784efc4
14 changed files with 159 additions and 10 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<modal-inner aria-label="提交信息"> <modal-inner aria-label="提交信息">
<p>自定义<b> 提交信息</b></p> <p>自定义 <b>{{ config.name }}</b> 提交信息</p>
<div class="modal__content"> <div class="modal__content">
<form-entry label="提交信息"> <form-entry label="提交信息">
<input slot="field" class="textfield" placeholder="提交信息非必填" type="text" v-model.trim="commitMessage" @keydown.enter="resolve()"> <input slot="field" class="textfield" placeholder="提交信息非必填" type="text" v-model.trim="commitMessage" @keydown.enter="resolve()">

View File

@ -17,6 +17,15 @@
<button class="workspace-entry__button button" @click="edit(id)" v-title="'编辑名称'"> <button class="workspace-entry__button button" @click="edit(id)" v-title="'编辑名称'">
<icon-pen></icon-pen> <icon-pen></icon-pen>
</button> </button>
<template v-if="workspace.providerId === 'giteeAppData' || workspace.providerId === 'githubWorkspace'
|| workspace.providerId === 'giteeWorkspace' || workspace.providerId === 'gitlabWorkspace' || workspace.providerId === 'giteaWorkspace'">
<button class="workspace-entry__button button" @click="stopAutoSync(id)" v-if="workspace.autoSync == undefined || workspace.autoSync" v-title="'关闭自动同步'">
<icon-sync-auto></icon-sync-auto>
</button>
<button class="workspace-entry__button button" @click="startAutoSync(id)" v-if="workspace.autoSync != undefined && !workspace.autoSync" v-title="'启动自动同步'">
<icon-sync-stop></icon-sync-stop>
</button>
</template>
<button class="workspace-entry__button button" @click="remove(id)" v-title="'删除'"> <button class="workspace-entry__button button" @click="remove(id)" v-title="'删除'">
<icon-delete></icon-delete> <icon-delete></icon-delete>
</button> </button>
@ -122,12 +131,53 @@ export default {
this.info('请先关闭文档空间,然后再将其删除。'); this.info('请先关闭文档空间,然后再将其删除。');
} else { } else {
try { try {
await store.dispatch('modal/open', 'removeWorkspace'); const workspace = this.workspacesById[id];
if (!workspace) {
return;
}
await store.dispatch('modal/open', {
type: 'removeWorkspace',
name: workspace.name,
});
workspaceSvc.removeWorkspace(id); workspaceSvc.removeWorkspace(id);
badgeSvc.addBadge('removeWorkspace'); badgeSvc.addBadge('removeWorkspace');
} catch (e) { /* Cancel */ } } catch (e) { /* Cancel */ }
} }
}, },
async stopAutoSync(id) {
const workspace = this.workspacesById[id];
if (!workspace) {
return;
}
await store.dispatch('modal/open', {
type: 'stopAutoSyncWorkspace',
name: workspace.name,
});
store.dispatch('workspace/patchWorkspacesById', {
[id]: {
...workspace,
autoSync: false,
},
});
badgeSvc.addBadge('stopAutoSyncWorkspace');
},
async startAutoSync(id) {
const workspace = this.workspacesById[id];
if (!workspace) {
return;
}
await store.dispatch('modal/open', {
type: 'autoSyncWorkspace',
name: workspace.name,
});
store.dispatch('workspace/patchWorkspacesById', {
[id]: {
...workspace,
autoSync: true,
},
});
badgeSvc.addBadge('autoSyncWorkspace');
},
}, },
created() { created() {
Object.keys(this.workspacesById).forEach(async (workspaceId) => { Object.keys(this.workspacesById).forEach(async (workspaceId) => {

View File

@ -207,6 +207,16 @@ export default [
'文档空间删除', '文档空间删除',
'使用“管理文档空间”对话框在本地删除文档空间。', '使用“管理文档空间”对话框在本地删除文档空间。',
), ),
new Feature(
'autoSyncWorkspace',
'文档空间启用自动同步',
'使用“管理文档空间”对话框启用自动同步。',
),
new Feature(
'stopAutoSyncWorkspace',
'文档空间关闭自动同步',
'使用“管理文档空间”对话框关闭自动同步。',
),
], ],
), ),
new Feature( new Feature(

View File

@ -6,6 +6,11 @@ const simpleModal = (contentHtml, rejectText, resolveText) => ({
/* eslint sort-keys: "error" */ /* eslint sort-keys: "error" */
export default { export default {
autoSyncWorkspace: simpleModal(
config => `<p>您将启动文档空间 <b>${config.name}</b >的自动同步。<br>启动后无法自定义提交信息。<br>你确定吗?</p>`,
'取消',
'确认启动',
),
commentDeletion: simpleModal( commentDeletion: simpleModal(
'<p>您将要删除评论。你确定吗?</p>', '<p>您将要删除评论。你确定吗?</p>',
'取消', '取消',
@ -46,7 +51,7 @@ export default {
'确认跳转', '确认跳转',
), ),
removeWorkspace: simpleModal( removeWorkspace: simpleModal(
'<p>您将要在本地删除文档空间ß。你确定吗?</p>', config => `<p>您将要在本地删除文档空间<b>${config.name}</b>。你确定吗?</p>`,
'取消', '取消',
'确认删除', '确认删除',
), ),
@ -71,6 +76,11 @@ export default {
'<p>此功能仅限于赞助商,因为它依赖于服务器资源。</p>', '<p>此功能仅限于赞助商,因为它依赖于服务器资源。</p>',
'好的,我明白了', '好的,我明白了',
), ),
stopAutoSyncWorkspace: simpleModal(
config => `<p>您将关闭文档空间 <b>${config.name}</b> 的自动同步。<br>关闭后您需要手动触发同步,但可以自定义提交信息。<br>你确定吗?</p>`,
'取消',
'确认关闭',
),
stripName: simpleModal( stripName: simpleModal(
config => `<p><b>${config.item.name}</b>包含非法字符。你想去掉它们吗?</p>`, config => `<p><b>${config.item.name}</b>包含非法字符。你想去掉它们吗?</p>`,
'取消', '取消',

5
src/icons/SyncAuto.vue Normal file
View File

@ -0,0 +1,5 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<path d="M 12 18 C 8.69 18 6 15.31 6 12 C 6 11 6.25 10.03 6.7 9.2 L 5.24 7.74 C 4.46 8.97 4 10.43 4 12 C 4 16.42 7.58 20 12 20 V 23 L 16 19 L 12 15 M 12 4 V 1 L 8 5 L 12 9 V 6 C 15.31 6 18 8.69 18 12 C 18 13 17.75 13.97 17.3 14.8 L 18.76 16.26 C 19.54 15.03 20 13.57 20 12 C 20 7.58 16.42 4 12 4 Z M 11 8 L 11 13 L 16 13 L 16 11 L 13 11 L 13 8 L 11 8 Z" />
</svg>
</template>

5
src/icons/SyncStop.vue Normal file
View File

@ -0,0 +1,5 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<path d="M 12 18 C 8.69 18 6 15.31 6 12 C 6 11 6.25 10.03 6.7 9.2 L 5.24 7.74 C 4.46 8.97 4 10.43 4 12 C 4 16.42 7.58 20 12 20 V 23 L 16 19 L 12 15 M 12 4 V 1 L 8 5 L 12 9 V 6 C 15.31 6 18 8.69 18 12 C 18 13 17.75 13.97 17.3 14.8 L 18.76 16.26 C 19.54 15.03 20 13.57 20 12 C 20 7.58 16.42 4 12 4 Z M 9 9 L 9 15 L 11 15 L 11 9 L 9 9 Z M 13 9 L 13 15 L 15 15 L 15 9 L 13 9 Z" />
</svg>
</template>

View File

@ -30,6 +30,8 @@ import Login from './Login';
import Logout from './Logout'; import Logout from './Logout';
import Sync from './Sync'; import Sync from './Sync';
import SyncOff from './SyncOff'; import SyncOff from './SyncOff';
import SyncAuto from './SyncAuto';
import SyncStop from './SyncStop';
import Upload from './Upload'; import Upload from './Upload';
import ViewList from './ViewList'; import ViewList from './ViewList';
import Download from './Download'; import Download from './Download';
@ -89,6 +91,8 @@ Vue.component('iconLogin', Login);
Vue.component('iconLogout', Logout); Vue.component('iconLogout', Logout);
Vue.component('iconSync', Sync); Vue.component('iconSync', Sync);
Vue.component('iconSyncOff', SyncOff); Vue.component('iconSyncOff', SyncOff);
Vue.component('iconSyncAuto', SyncAuto);
Vue.component('iconSyncStop', SyncStop);
Vue.component('iconUpload', Upload); Vue.component('iconUpload', Upload);
Vue.component('iconViewList', ViewList); Vue.component('iconViewList', ViewList);
Vue.component('iconDownload', Download); Vue.component('iconDownload', Download);

View File

@ -134,6 +134,7 @@ export default new Provider({
path: getAbsolutePath(syncData), path: getAbsolutePath(syncData),
content: '', content: '',
sha: gitWorkspaceSvc.shaByPath[syncData.id], sha: gitWorkspaceSvc.shaByPath[syncData.id],
commitMessage: item.commitMessage,
}); });
// Return sync data to save // Return sync data to save
@ -193,7 +194,12 @@ export default new Provider({
}, },
}; };
}, },
async uploadWorkspaceContent({ token, content, file }) { async uploadWorkspaceContent({
token,
content,
file,
commitMessage,
}) {
const path = store.getters.gitPathsByItemId[file.id]; const path = store.getters.gitPathsByItemId[file.id];
const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`; const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`;
const sha = gitWorkspaceSvc.shaByPath[path]; const sha = gitWorkspaceSvc.shaByPath[path];
@ -203,6 +209,7 @@ export default new Provider({
path: absolutePath, path: absolutePath,
content: Provider.serializeContent(content), content: Provider.serializeContent(content),
sha, sha,
commitMessage,
}); });
// Return new sync data // Return new sync data

View File

@ -67,6 +67,7 @@ export default new Provider({
path: syncData.id, path: syncData.id,
content: '', content: '',
sha: gitWorkspaceSvc.shaByPath[syncData.id], sha: gitWorkspaceSvc.shaByPath[syncData.id],
commitMessage: item.commitMessage,
}); });
// Return sync data to save // Return sync data to save
@ -138,7 +139,12 @@ export default new Provider({
}, },
}; };
}, },
async uploadWorkspaceContent({ token, content, file }) { async uploadWorkspaceContent({
token,
content,
file,
commitMessage,
}) {
const path = store.getters.gitPathsByItemId[file.id]; const path = store.getters.gitPathsByItemId[file.id];
const res = await giteeHelper.uploadFile({ const res = await giteeHelper.uploadFile({
owner: token.name, owner: token.name,
@ -148,6 +154,7 @@ export default new Provider({
path, path,
content: Provider.serializeContent(content), content: Provider.serializeContent(content),
sha: gitWorkspaceSvc.shaByPath[path], sha: gitWorkspaceSvc.shaByPath[path],
commitMessage,
}); });
// Return new sync data // Return new sync data

View File

@ -119,6 +119,7 @@ export default new Provider({
path: getAbsolutePath(syncData), path: getAbsolutePath(syncData),
content: '', content: '',
sha: gitWorkspaceSvc.shaByPath[syncData.id], sha: gitWorkspaceSvc.shaByPath[syncData.id],
commitMessage: item.commitMessage,
}); });
// Return sync data to save // Return sync data to save
@ -178,7 +179,12 @@ export default new Provider({
}, },
}; };
}, },
async uploadWorkspaceContent({ token, content, file }) { async uploadWorkspaceContent({
token,
content,
file,
commitMessage,
}) {
const path = store.getters.gitPathsByItemId[file.id]; const path = store.getters.gitPathsByItemId[file.id];
const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`; const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`;
const res = await giteeHelper.uploadFile({ const res = await giteeHelper.uploadFile({
@ -187,6 +193,7 @@ export default new Provider({
path: absolutePath, path: absolutePath,
content: Provider.serializeContent(content), content: Provider.serializeContent(content),
sha: gitWorkspaceSvc.shaByPath[path], sha: gitWorkspaceSvc.shaByPath[path],
commitMessage,
}); });
// Return new sync data // Return new sync data

View File

@ -119,6 +119,7 @@ export default new Provider({
path: getAbsolutePath(syncData), path: getAbsolutePath(syncData),
content: '', content: '',
sha: gitWorkspaceSvc.shaByPath[syncData.id], sha: gitWorkspaceSvc.shaByPath[syncData.id],
commitMessage: item.commitMessage,
}); });
// Return sync data to save // Return sync data to save
@ -178,7 +179,12 @@ export default new Provider({
}, },
}; };
}, },
async uploadWorkspaceContent({ token, content, file }) { async uploadWorkspaceContent({
token,
content,
file,
commitMessage,
}) {
const path = store.getters.gitPathsByItemId[file.id]; const path = store.getters.gitPathsByItemId[file.id];
const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`; const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`;
const res = await githubHelper.uploadFile({ const res = await githubHelper.uploadFile({
@ -187,6 +193,7 @@ export default new Provider({
path: absolutePath, path: absolutePath,
content: Provider.serializeContent(content), content: Provider.serializeContent(content),
sha: gitWorkspaceSvc.shaByPath[path], sha: gitWorkspaceSvc.shaByPath[path],
commitMessage,
}); });
// Return new sync data // Return new sync data

View File

@ -134,6 +134,7 @@ export default new Provider({
path: getAbsolutePath(syncData), path: getAbsolutePath(syncData),
content: '', content: '',
sha: gitWorkspaceSvc.shaByPath[syncData.id], sha: gitWorkspaceSvc.shaByPath[syncData.id],
commitMessage: item.commitMessage,
}); });
// Return sync data to save // Return sync data to save
@ -193,7 +194,12 @@ export default new Provider({
}, },
}; };
}, },
async uploadWorkspaceContent({ token, content, file }) { async uploadWorkspaceContent({
token,
content,
file,
commitMessage,
}) {
const path = store.getters.gitPathsByItemId[file.id]; const path = store.getters.gitPathsByItemId[file.id];
const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`; const absolutePath = `${store.getters['workspace/currentWorkspace'].path || ''}${path}`;
const sha = gitWorkspaceSvc.shaByPath[path]; const sha = gitWorkspaceSvc.shaByPath[path];
@ -203,6 +209,7 @@ export default new Provider({
path: absolutePath, path: absolutePath,
content: Provider.serializeContent(content), content: Provider.serializeContent(content),
sha, sha,
commitMessage,
}); });
// Return new sync data // Return new sync data

View File

@ -148,7 +148,10 @@ const createPublishLocation = (publishLocation, featureId) => {
let commitMsg = ''; let commitMsg = '';
if (gitProviderIds.indexOf(publishLocation.providerId) > -1) { if (gitProviderIds.indexOf(publishLocation.providerId) > -1) {
try { try {
const { commitMessage } = await store.dispatch('modal/open', { type: 'commitMessage' }); const { commitMessage } = await store.dispatch('modal/open', {
type: 'commitMessage',
name: currentFile.name,
});
commitMsg = commitMessage; commitMsg = commitMessage;
} catch (e) { } catch (e) {
return; return;

View File

@ -73,6 +73,14 @@ const isAutoSyncReady = () => {
return Date.now() > autoSyncEvery + getLastStoredSyncActivity(); return Date.now() > autoSyncEvery + getLastStoredSyncActivity();
}; };
/**
* 是否已启用工作空间的自动同步 没有配置 默认是启用了的
*/
const isEnableAutoSyncWorkspace = () => {
const workspace = store.getters['workspace/currentWorkspace'];
return workspace.autoSync === undefined || workspace.autoSync;
};
/** /**
* Update the lastSyncActivity, assuming we have the lock. * Update the lastSyncActivity, assuming we have the lock.
*/ */
@ -361,7 +369,7 @@ const syncFile = async (fileId, syncContext = new SyncContext()) => {
return content; return content;
}; };
const uploadContent = async (content, ifNotTooLate) => { const uploadContent = async (content, ifNotTooLate, commitMessage) => {
// On simple provider, call simply uploadContent // On simple provider, call simply uploadContent
if (syncLocation.id !== 'main') { if (syncLocation.id !== 'main') {
return provider.uploadContent(token, content, syncLocation, ifNotTooLate); return provider.uploadContent(token, content, syncLocation, ifNotTooLate);
@ -377,6 +385,7 @@ const syncFile = async (fileId, syncContext = new SyncContext()) => {
updateSyncData(await provider.uploadWorkspaceContent({ updateSyncData(await provider.uploadWorkspaceContent({
token, token,
content, content,
commitMessage,
// Use deepCopy to freeze item // Use deepCopy to freeze item
file: utils.deepCopy(store.state.file.itemsById[fileId]), file: utils.deepCopy(store.state.file.itemsById[fileId]),
contentSyncData: oldContentSyncData, contentSyncData: oldContentSyncData,
@ -485,6 +494,22 @@ const syncFile = async (fileId, syncContext = new SyncContext()) => {
syncContext.restartSkipContents = true; syncContext.restartSkipContents = true;
} }
const currentWorkspace = store.getters['workspace/currentWorkspace'];
const isGit = !!store.getters['workspace/currentWorkspaceIsGit'];
let commitMsg = '';
// 是git 并且未配置自动同步或启用了自动同步 并且文档类型是content
if (isGit && (currentWorkspace.autoSync !== undefined && !currentWorkspace.autoSync)) {
const file = store.state.file.itemsById[fileId];
try {
const { commitMessage } = await store.dispatch('modal/open', {
type: 'commitMessage',
name: file.name,
});
commitMsg = commitMessage;
} catch (e) {
return;
}
}
// Upload merged content // Upload merged content
const item = { const item = {
...mergedContent, ...mergedContent,
@ -493,6 +518,7 @@ const syncFile = async (fileId, syncContext = new SyncContext()) => {
const syncLocationToStore = await uploadContent( const syncLocationToStore = await uploadContent(
item, item,
tooLateChecker(restartContentSyncAfter), tooLateChecker(restartContentSyncAfter),
commitMsg,
); );
// Replace sync location if modified // Replace sync location if modified
@ -938,6 +964,7 @@ export default {
&& networkSvc.isUserActive() && networkSvc.isUserActive()
&& isSyncWindow() && isSyncWindow()
&& isAutoSyncReady() && isAutoSyncReady()
&& isEnableAutoSyncWorkspace()
) { ) {
requestSync(); requestSync();
} }