Skip to content

Commit

Permalink
添加几个同步功能
Browse files Browse the repository at this point in the history
  • Loading branch information
htmambo committed Feb 29, 2024
1 parent aa20595 commit f091636
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 44 deletions.
15 changes: 15 additions & 0 deletions app/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,21 @@ function SyncConfigModal(props: { onClose?: () => void }) {
}}
></input>
</ListItem>
<ListItem
title={Locale.Settings.Sync.Config.OverwriteRemote.Title}
subTitle={Locale.Settings.Sync.Config.OverwriteRemote.SubTitle}
>
<input
type="checkbox"
checked={syncStore.enableOverwriteRemote}
onChange={(e) => {
syncStore.update(
(config) =>
(config.enableOverwriteRemote = e.currentTarget.checked),
);
}}
></input>
</ListItem>
<ListItem
title={Locale.Settings.Sync.Config.OnlySyncUserData.Title}
subTitle={Locale.Settings.Sync.Config.OnlySyncUserData.SubTitle}
Expand Down
9 changes: 6 additions & 3 deletions app/locales/cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,17 @@ const cn = {
Title: "代理地址",
SubTitle: "仅适用于本项目自带的跨域代理",
},

OverwriteLocal: {
Title: "覆盖本地",
SubTitle: "放弃本地所有数据,使用远程信息直接覆盖本地(不保留本地任何数据)",
},
OverwriteRemote: {
Title: "覆盖远程",
SubTitle: "放弃远程所有数据,使用本地信息直接覆盖远程(不保留远程任何数据)",
},
OnlySyncUserData: {
Title: "同步远程数据,忽略配置",
SubTitle: "仅同步其他来源的数据,而不同步远程的控制设置",
Title: "同步远程用户数据,忽略配置",
SubTitle: "保留本地控制设置,将用户数据与远程合并后同步",
},
WebDav: {
Endpoint: "WebDAV 地址",
Expand Down
13 changes: 9 additions & 4 deletions app/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,18 @@ const en: LocaleType = {
"Only applicable to the built-in CORS proxy for this project",
},
OverwriteLocal: {
Title: "Full Overwrite",
Title: "Overwrite Local",
SubTitle:
"Only applicable to the overwrite access control setting such as an access code",
"Abandon all local data and use remote information to directly overwrite local (without retaining any local data)",
},
OverwriteRemote: {
Title: "Overwrite Remote",
SubTitle:
"Drop all data from the remote and use local information to directly overwrite the remote (without retaining any data from the remote)",
},
OnlySyncUserData: {
Title: "Synchronize remote data, ignore configuration",
SubTitle: "Synchronize only data from other sources, not remote control settings",
Title: "Synchronize remote user data, ignore configuration",
SubTitle: "Preserve local control settings and synchronize user data with remote merge",
},
WebDav: {
Endpoint: "WebDAV Endpoint",
Expand Down
89 changes: 52 additions & 37 deletions app/store/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const DEFAULT_SYNC_STATE = {
lastProvider: "",
lastUpdateTime: 0,
syncing: false,
// 放弃远程数据,以本地数据完全覆盖远程
enableOverwriteRemote: false,
// 放弃本地数据,以远程数据完全覆盖本地
enableOverwriteLocal: false,
// 仅同步用户数据(聊天、自定义面具以及提示)
Expand Down Expand Up @@ -115,53 +117,66 @@ export const useSyncStore = createPersistStore(

try {
set({ syncing: true }); // Set syncing to true before performing the sync
const tmpRemoteState = JSON.parse(
await client.get(config.username),
) as AppState;
// 替换remoteState中的access-control、app-config为localState中的值
const remoteState = { ...tmpRemoteState };
if (get().onlysyncuserdata) {
// 如果onlysyncuserdata为true,不同步access-control、app-config。需要生成一个新的用于合并的变量,因为remoteState是只读的
remoteState[StoreKey.Access] = localState[StoreKey.Access];
remoteState[StoreKey.Config] = localState[StoreKey.Config];
}
mergeAppState(localState, remoteState);
const sessions = localState[StoreKey.Chat].sessions;
const currentSession =
sessions[localState[StoreKey.Chat].currentSessionIndex];
const filteredTopic =
currentSession.topic === "New Conversation" &&
currentSession.messages.length === 0;

if (filteredTopic) {
const remoteSessions = remoteState[StoreKey.Chat].sessions;
const remoteCurrentSession =
remoteSessions[remoteState[StoreKey.Chat].currentSessionIndex];
const remoteFilteredTopic =
remoteCurrentSession.topic === "New Conversation" &&
remoteCurrentSession.messages.length > 0;

if (!remoteFilteredTopic) {
localState[StoreKey.Chat].sessions[
localState[StoreKey.Chat].currentSessionIndex
].mask = {
...currentSession.mask,
name: remoteCurrentSession.mask.name,
};
// 除了基本的双向同步以外,还需要实现以下的同步方式
// 1. 覆盖远程所有数据
// 2. 覆盖本地所有数据
// 3. 仅同步用户数据(聊天、自定义面具以及提示)

// 1. 覆盖远程所有数据(这时不需要从远程下载)
if (get().enableOverwriteRemote) {
} else {
const tmpRemoteState = JSON.parse(
await client.get(config.username),
) as AppState;
// 3. 仅同步用户数据(替换remoteState中的access-control、app-config为localState中的值)
const remoteState = { ...tmpRemoteState };
if (get().onlysyncuserdata) {
// 如果onlysyncuserdata为true,不同步access-control、app-config。需要生成一个新的用于合并的变量,因为remoteState是只读的
remoteState[StoreKey.Access] = localState[StoreKey.Access];
remoteState[StoreKey.Config] = localState[StoreKey.Config];
}
// 2. 覆盖本地所有数据(这时不需要上传到远程,覆盖完直接返回)
if (get().enableOverwriteLocal) {
setLocalAppState(tmpRemoteState);
this.markSyncTime();
set({ syncing: false });
return true; // Add the return statement here
}
mergeAppState(localState, remoteState);
const sessions = localState[StoreKey.Chat].sessions;
const currentSession =
sessions[localState[StoreKey.Chat].currentSessionIndex];
const filteredTopic =
currentSession.topic === "New Conversation" &&
currentSession.messages.length === 0;

if (filteredTopic) {
const remoteSessions = remoteState[StoreKey.Chat].sessions;
const remoteCurrentSession =
remoteSessions[remoteState[StoreKey.Chat].currentSessionIndex];
const remoteFilteredTopic =
remoteCurrentSession.topic === "New Conversation" &&
remoteCurrentSession.messages.length > 0;

if (!remoteFilteredTopic) {
localState[StoreKey.Chat].sessions[
localState[StoreKey.Chat].currentSessionIndex
].mask = {
...currentSession.mask,
name: remoteCurrentSession.mask.name,
};
}
}
setLocalAppState(localState);
}

setLocalAppState(localState);
} catch (e) {
console.log("[Sync] failed to get remote state", e);

}

await client.set(config.username, JSON.stringify(localState));

this.markSyncTime();
set({ syncing: false });

return true; // Add the return statement here
},

Expand Down

0 comments on commit f091636

Please sign in to comment.