Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
c203b1d0
Unverified
提交
c203b1d0
authored
5月 09, 2025
作者:
Will Chen
提交者:
GitHub
5月 09, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
make checkout version and revert version fit pattern (#118)
上级
8d61659c
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
161 行增加
和
92 行删除
+161
-92
ChatPanel.tsx
src/components/ChatPanel.tsx
+1
-0
ChatHeader.tsx
src/components/chat/ChatHeader.tsx
+11
-18
VersionPane.tsx
src/components/chat/VersionPane.tsx
+67
-28
useCheckoutVersion.ts
src/hooks/useCheckoutVersion.ts
+38
-0
useVersions.ts
src/hooks/useVersions.ts
+13
-18
version_handlers.ts
src/ipc/handlers/version_handlers.ts
+5
-6
ipc_client.ts
src/ipc/ipc_client.ts
+10
-22
assert.ts
src/lib/assert.ts
+8
-0
renderer.tsx
src/renderer.tsx
+8
-0
没有找到文件。
src/components/ChatPanel.tsx
浏览文件 @
c203b1d0
...
@@ -117,6 +117,7 @@ export function ChatPanel({
...
@@ -117,6 +117,7 @@ export function ChatPanel({
return
(
return
(
<
div
className=
"flex flex-col h-full"
>
<
div
className=
"flex flex-col h-full"
>
<
ChatHeader
<
ChatHeader
isVersionPaneOpen=
{
isVersionPaneOpen
}
isPreviewOpen=
{
isPreviewOpen
}
isPreviewOpen=
{
isPreviewOpen
}
onTogglePreview=
{
onTogglePreview
}
onTogglePreview=
{
onTogglePreview
}
onVersionClick=
{
()
=>
setIsVersionPaneOpen
(
!
isVersionPaneOpen
)
}
onVersionClick=
{
()
=>
setIsVersionPaneOpen
(
!
isVersionPaneOpen
)
}
...
...
src/components/chat/ChatHeader.tsx
浏览文件 @
c203b1d0
...
@@ -21,17 +21,20 @@ import { useRouter } from "@tanstack/react-router";
...
@@ -21,17 +21,20 @@ import { useRouter } from "@tanstack/react-router";
import
{
selectedChatIdAtom
}
from
"@/atoms/chatAtoms"
;
import
{
selectedChatIdAtom
}
from
"@/atoms/chatAtoms"
;
import
{
useChats
}
from
"@/hooks/useChats"
;
import
{
useChats
}
from
"@/hooks/useChats"
;
import
{
showError
}
from
"@/lib/toast"
;
import
{
showError
}
from
"@/lib/toast"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
}
from
"react"
;
import
{
useStreamChat
}
from
"@/hooks/useStreamChat"
;
import
{
useStreamChat
}
from
"@/hooks/useStreamChat"
;
import
{
useCurrentBranch
}
from
"@/hooks/useCurrentBranch"
;
import
{
useCurrentBranch
}
from
"@/hooks/useCurrentBranch"
;
import
{
useCheckoutVersion
}
from
"@/hooks/useCheckoutVersion"
;
interface
ChatHeaderProps
{
interface
ChatHeaderProps
{
isVersionPaneOpen
:
boolean
;
isPreviewOpen
:
boolean
;
isPreviewOpen
:
boolean
;
onTogglePreview
:
()
=>
void
;
onTogglePreview
:
()
=>
void
;
onVersionClick
:
()
=>
void
;
onVersionClick
:
()
=>
void
;
}
}
export
function
ChatHeader
({
export
function
ChatHeader
({
isVersionPaneOpen
,
isPreviewOpen
,
isPreviewOpen
,
onTogglePreview
,
onTogglePreview
,
onVersionClick
,
onVersionClick
,
...
@@ -41,7 +44,6 @@ export function ChatHeader({
...
@@ -41,7 +44,6 @@ export function ChatHeader({
const
{
navigate
}
=
useRouter
();
const
{
navigate
}
=
useRouter
();
const
[
selectedChatId
,
setSelectedChatId
]
=
useAtom
(
selectedChatIdAtom
);
const
[
selectedChatId
,
setSelectedChatId
]
=
useAtom
(
selectedChatIdAtom
);
const
{
refreshChats
}
=
useChats
(
appId
);
const
{
refreshChats
}
=
useChats
(
appId
);
const
[
checkingOutMain
,
setCheckingOutMain
]
=
useState
(
false
);
const
{
isStreaming
}
=
useStreamChat
();
const
{
isStreaming
}
=
useStreamChat
();
const
{
const
{
...
@@ -50,6 +52,8 @@ export function ChatHeader({
...
@@ -50,6 +52,8 @@ export function ChatHeader({
refetchBranchInfo
,
refetchBranchInfo
,
}
=
useCurrentBranch
(
appId
);
}
=
useCurrentBranch
(
appId
);
const
{
checkoutVersion
,
isCheckingOutVersion
}
=
useCheckoutVersion
();
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
appId
)
{
if
(
appId
)
{
refetchBranchInfo
();
refetchBranchInfo
();
...
@@ -58,19 +62,7 @@ export function ChatHeader({
...
@@ -58,19 +62,7 @@ export function ChatHeader({
const
handleCheckoutMainBranch
=
async
()
=>
{
const
handleCheckoutMainBranch
=
async
()
=>
{
if
(
!
appId
)
return
;
if
(
!
appId
)
return
;
await
checkoutVersion
({
appId
,
versionId
:
"main"
});
try
{
setCheckingOutMain
(
true
);
await
IpcClient
.
getInstance
().
checkoutVersion
({
appId
,
versionId
:
"main"
,
});
await
refetchBranchInfo
();
}
catch
(
error
)
{
showError
(
`Failed to checkout main branch:
${
error
}
`
);
}
finally
{
setCheckingOutMain
(
false
);
}
};
};
const
handleNewChat
=
async
()
=>
{
const
handleNewChat
=
async
()
=>
{
...
@@ -100,7 +92,8 @@ export function ChatHeader({
...
@@ -100,7 +92,8 @@ export function ChatHeader({
return
(
return
(
<
div
className=
"flex flex-col w-full @container"
>
<
div
className=
"flex flex-col w-full @container"
>
{
isNotMainBranch
&&
(
{
/* If the version pane is open, it's expected to not always be on the main branch. */
}
{
isNotMainBranch
&&
!
isVersionPaneOpen
&&
(
<
div
className=
"flex flex-col @sm:flex-row items-center justify-between px-4 py-2 bg-amber-100 dark:bg-amber-900 text-amber-800 dark:text-amber-200"
>
<
div
className=
"flex flex-col @sm:flex-row items-center justify-between px-4 py-2 bg-amber-100 dark:bg-amber-900 text-amber-800 dark:text-amber-200"
>
<
div
className=
"flex items-center gap-2 text-sm"
>
<
div
className=
"flex items-center gap-2 text-sm"
>
<
GitBranch
size=
{
16
}
/>
<
GitBranch
size=
{
16
}
/>
...
@@ -138,9 +131,9 @@ export function ChatHeader({
...
@@ -138,9 +131,9 @@ export function ChatHeader({
variant=
"outline"
variant=
"outline"
size=
"sm"
size=
"sm"
onClick=
{
handleCheckoutMainBranch
}
onClick=
{
handleCheckoutMainBranch
}
disabled=
{
checkingOutMai
n
||
branchInfoLoading
}
disabled=
{
isCheckingOutVersio
n
||
branchInfoLoading
}
>
>
{
checkingOutMai
n
?
"Checking out..."
:
"Switch to main branch"
}
{
isCheckingOutVersio
n
?
"Checking out..."
:
"Switch to main branch"
}
</
Button
>
</
Button
>
</
div
>
</
div
>
)
}
)
}
...
...
src/components/chat/VersionPane.tsx
浏览文件 @
c203b1d0
...
@@ -4,9 +4,9 @@ import { useVersions } from "@/hooks/useVersions";
...
@@ -4,9 +4,9 @@ import { useVersions } from "@/hooks/useVersions";
import
{
formatDistanceToNow
}
from
"date-fns"
;
import
{
formatDistanceToNow
}
from
"date-fns"
;
import
{
RotateCcw
,
X
}
from
"lucide-react"
;
import
{
RotateCcw
,
X
}
from
"lucide-react"
;
import
type
{
Version
}
from
"@/ipc/ipc_types"
;
import
type
{
Version
}
from
"@/ipc/ipc_types"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
import
{
cn
}
from
"@/lib/utils"
;
import
{
cn
}
from
"@/lib/utils"
;
import
{
useEffect
}
from
"react"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
useCheckoutVersion
}
from
"@/hooks/useCheckoutVersion"
;
interface
VersionPaneProps
{
interface
VersionPaneProps
{
isVisible
:
boolean
;
isVisible
:
boolean
;
...
@@ -15,31 +15,69 @@ interface VersionPaneProps {
...
@@ -15,31 +15,69 @@ interface VersionPaneProps {
export
function
VersionPane
({
isVisible
,
onClose
}:
VersionPaneProps
)
{
export
function
VersionPane
({
isVisible
,
onClose
}:
VersionPaneProps
)
{
const
appId
=
useAtomValue
(
selectedAppIdAtom
);
const
appId
=
useAtomValue
(
selectedAppIdAtom
);
const
{
versions
,
loading
,
refreshVersions
,
revertVersion
}
=
const
{
useVersions
(
appId
);
versions
:
liveVersions
,
refreshVersions
,
revertVersion
,
}
=
useVersions
(
appId
);
const
[
selectedVersionId
,
setSelectedVersionId
]
=
useAtom
(
const
[
selectedVersionId
,
setSelectedVersionId
]
=
useAtom
(
selectedVersionIdAtom
,
selectedVersionIdAtom
,
);
);
const
{
checkoutVersion
,
isCheckingOutVersion
}
=
useCheckoutVersion
();
const
wasVisibleRef
=
useRef
(
false
);
const
[
cachedVersions
,
setCachedVersions
]
=
useState
<
Version
[]
>
([]);
useEffect
(()
=>
{
useEffect
(()
=>
{
async
function
updateVersions
()
{
async
function
updatePaneState
()
{
// Refresh versions in case the user updated versions outside of the app
// When pane becomes visible after being closed
// (e.g. manually using git).
if
(
isVisible
&&
!
wasVisibleRef
.
current
)
{
// Avoid loading state which causes brief flash of loading state.
if
(
appId
)
{
await
refreshVersions
();
setCachedVersions
(
liveVersions
);
}
}
// Reset when closing
if
(
!
isVisible
&&
selectedVersionId
)
{
if
(
!
isVisible
&&
selectedVersionId
)
{
setSelectedVersionId
(
null
);
setSelectedVersionId
(
null
);
await
IpcClient
.
getInstance
().
checkoutVersion
({
if
(
appId
)
{
appId
:
appId
!
,
await
checkoutVersion
({
appId
,
versionId
:
"main"
});
versionId
:
"main"
,
}
});
}
}
refreshVersions
();
wasVisibleRef
.
current
=
isVisible
;
}
}
updateVersions
();
updatePaneState
();
},
[
isVisible
,
refreshVersions
]);
},
[
isVisible
,
selectedVersionId
,
setSelectedVersionId
,
appId
,
checkoutVersion
,
refreshVersions
,
liveVersions
,
]);
// Initial load of cached versions when live versions become available
useEffect
(()
=>
{
if
(
isVisible
&&
liveVersions
.
length
>
0
&&
cachedVersions
.
length
===
0
)
{
setCachedVersions
(
liveVersions
);
}
},
[
isVisible
,
liveVersions
,
cachedVersions
.
length
]);
if
(
!
isVisible
)
{
if
(
!
isVisible
)
{
return
null
;
return
null
;
}
}
const
handleVersionClick
=
async
(
versionOid
:
string
)
=>
{
if
(
appId
)
{
setSelectedVersionId
(
versionOid
);
await
checkoutVersion
({
appId
,
versionId
:
versionOid
});
}
};
const
versions
=
cachedVersions
.
length
>
0
?
cachedVersions
:
liveVersions
;
return
(
return
(
<
div
className=
"h-full border-t border-2 border-border w-full"
>
<
div
className=
"h-full border-t border-2 border-border w-full"
>
<
div
className=
"p-2 border-b border-border flex items-center justify-between"
>
<
div
className=
"p-2 border-b border-border flex items-center justify-between"
>
...
@@ -53,26 +91,25 @@ export function VersionPane({ isVisible, onClose }: VersionPaneProps) {
...
@@ -53,26 +91,25 @@ export function VersionPane({ isVisible, onClose }: VersionPaneProps) {
</
button
>
</
button
>
</
div
>
</
div
>
<
div
className=
"overflow-y-auto h-[calc(100%-60px)]"
>
<
div
className=
"overflow-y-auto h-[calc(100%-60px)]"
>
{
loading
?
(
{
versions
.
length
===
0
?
(
<
div
className=
"p-4 "
>
Loading versions...
</
div
>
)
:
versions
.
length
===
0
?
(
<
div
className=
"p-4 "
>
No versions available
</
div
>
<
div
className=
"p-4 "
>
No versions available
</
div
>
)
:
(
)
:
(
<
div
className=
"divide-y divide-border"
>
<
div
className=
"divide-y divide-border"
>
{
versions
.
map
((
version
:
Version
,
index
)
=>
(
{
versions
.
map
((
version
:
Version
,
index
)
=>
(
<
div
<
div
key=
{
version
.
oid
}
key=
{
version
.
oid
}
className=
{
`px-4 py-2 hover:bg-(--background-lightest) cursor-pointer ${
className=
{
cn
(
selectedVersionId === version.oid
"px-4 py-2 hover:bg-(--background-lightest) cursor-pointer"
,
? "bg-(--background-lightest)"
selectedVersionId
===
version
.
oid
&&
: ""
"bg-(--background-lightest)"
,
}`
}
isCheckingOutVersion
&&
selectedVersionId
===
version
.
oid
&&
"opacity-50 cursor-not-allowed"
,
)
}
onClick=
{
()
=>
{
onClick=
{
()
=>
{
IpcClient
.
getInstance
().
checkoutVersion
({
if
(
!
isCheckingOutVersion
)
{
appId
:
appId
!
,
handleVersionClick
(
version
.
oid
);
versionId
:
version
.
oid
,
}
});
setSelectedVersionId
(
version
.
oid
);
}
}
}
}
>
>
<
div
className=
"flex items-center justify-between"
>
<
div
className=
"flex items-center justify-between"
>
...
@@ -115,6 +152,8 @@ export function VersionPane({ isVisible, onClose }: VersionPaneProps) {
...
@@ -115,6 +152,8 @@ export function VersionPane({ isVisible, onClose }: VersionPaneProps) {
await
revertVersion
({
await
revertVersion
({
versionId
:
version
.
oid
,
versionId
:
version
.
oid
,
});
});
// Close the pane after revert to force a refresh on next open
onClose
();
}
}
}
}
className=
{
cn
(
className=
{
cn
(
"invisible mt-1 flex items-center gap-1 px-2 py-0.5 text-sm font-medium bg-(--primary) text-(--primary-foreground) hover:bg-background-lightest rounded-md transition-colors"
,
"invisible mt-1 flex items-center gap-1 px-2 py-0.5 text-sm font-medium bg-(--primary) text-(--primary-foreground) hover:bg-background-lightest rounded-md transition-colors"
,
...
...
src/hooks/useCheckoutVersion.ts
0 → 100644
浏览文件 @
c203b1d0
import
{
useMutation
,
useQueryClient
}
from
"@tanstack/react-query"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
interface
CheckoutVersionVariables
{
appId
:
number
;
versionId
:
string
;
}
export
function
useCheckoutVersion
()
{
const
queryClient
=
useQueryClient
();
const
{
isPending
:
isCheckingOutVersion
,
mutateAsync
:
checkoutVersion
}
=
useMutation
<
void
,
Error
,
CheckoutVersionVariables
>
({
mutationFn
:
async
({
appId
,
versionId
})
=>
{
if
(
appId
===
null
)
{
// Should be caught by UI logic before calling, but as a safeguard.
throw
new
Error
(
"App ID is null, cannot checkout version."
);
}
const
ipcClient
=
IpcClient
.
getInstance
();
await
ipcClient
.
checkoutVersion
({
appId
,
versionId
});
},
onSuccess
:
(
_
,
variables
)
=>
{
// Invalidate queries that depend on the current version/branch
queryClient
.
invalidateQueries
({
queryKey
:
[
"currentBranch"
,
variables
.
appId
],
});
queryClient
.
invalidateQueries
({
queryKey
:
[
"versions"
,
variables
.
appId
],
});
},
meta
:
{
showErrorToast
:
true
},
});
return
{
checkoutVersion
,
isCheckingOutVersion
,
};
}
src/hooks/useVersions.ts
浏览文件 @
c203b1d0
import
{
use
Callback
,
use
Effect
}
from
"react"
;
import
{
useEffect
}
from
"react"
;
import
{
useAtom
,
useAtomValue
}
from
"jotai"
;
import
{
useAtom
,
useAtomValue
}
from
"jotai"
;
import
{
versionsListAtom
}
from
"@/atoms/appAtoms"
;
import
{
versionsListAtom
}
from
"@/atoms/appAtoms"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
import
{
IpcClient
}
from
"@/ipc/ipc_client"
;
import
{
showError
}
from
"@/lib/toast"
;
import
{
chatMessagesAtom
,
selectedChatIdAtom
}
from
"@/atoms/chatAtoms"
;
import
{
chatMessagesAtom
,
selectedChatIdAtom
}
from
"@/atoms/chatAtoms"
;
import
{
useQuery
,
useMutation
,
useQueryClient
}
from
"@tanstack/react-query"
;
import
{
useQuery
,
useMutation
,
useQueryClient
}
from
"@tanstack/react-query"
;
import
type
{
Version
}
from
"@/ipc/ipc_types"
;
import
type
{
Version
}
from
"@/ipc/ipc_types"
;
...
@@ -41,33 +41,28 @@ export function useVersions(appId: number | null) {
...
@@ -41,33 +41,28 @@ export function useVersions(appId: number | null) {
const
revertVersionMutation
=
useMutation
<
void
,
Error
,
{
versionId
:
string
}
>
(
const
revertVersionMutation
=
useMutation
<
void
,
Error
,
{
versionId
:
string
}
>
(
{
{
mutationFn
:
async
({
versionId
}:
{
versionId
:
string
})
=>
{
mutationFn
:
async
({
versionId
}:
{
versionId
:
string
})
=>
{
if
(
appId
===
null
)
{
const
currentAppId
=
appId
;
if
(
currentAppId
===
null
)
{
throw
new
Error
(
"App ID is null"
);
throw
new
Error
(
"App ID is null"
);
}
}
const
ipcClient
=
IpcClient
.
getInstance
();
const
ipcClient
=
IpcClient
.
getInstance
();
await
ipcClient
.
revertVersion
({
appId
,
previousVersionId
:
versionId
});
await
ipcClient
.
revertVersion
({
appId
:
currentAppId
,
previousVersionId
:
versionId
,
});
},
},
onSuccess
:
async
()
=>
{
onSuccess
:
async
()
=>
{
await
queryClient
.
invalidateQueries
({
queryKey
:
[
"versions"
,
appId
]
});
await
queryClient
.
invalidateQueries
({
queryKey
:
[
"versions"
,
appId
]
});
await
queryClient
.
invalidateQueries
({
queryKey
:
[
"currentBranch"
,
appId
],
});
if
(
selectedChatId
)
{
if
(
selectedChatId
)
{
const
chat
=
await
IpcClient
.
getInstance
().
getChat
(
selectedChatId
);
const
chat
=
await
IpcClient
.
getInstance
().
getChat
(
selectedChatId
);
setMessages
(
chat
.
messages
);
setMessages
(
chat
.
messages
);
}
}
},
},
onError
:
(
e
:
Error
)
=>
{
meta
:
{
showErrorToast
:
true
},
showError
(
e
);
},
},
);
const
revertVersion
=
useCallback
(
async
({
versionId
}:
{
versionId
:
string
})
=>
{
if
(
appId
===
null
)
{
return
;
}
await
revertVersionMutation
.
mutateAsync
({
versionId
});
},
},
[
appId
,
revertVersionMutation
],
);
);
return
{
return
{
...
@@ -75,6 +70,6 @@ export function useVersions(appId: number | null) {
...
@@ -75,6 +70,6 @@ export function useVersions(appId: number | null) {
loading
,
loading
,
error
,
error
,
refreshVersions
,
refreshVersions
,
revertVersion
,
revertVersion
:
revertVersionMutation
.
mutateAsync
,
};
};
}
}
src/ipc/handlers/version_handlers.ts
浏览文件 @
c203b1d0
...
@@ -94,7 +94,7 @@ export function registerVersionHandlers() {
...
@@ -94,7 +94,7 @@ export function registerVersionHandlers() {
appId
,
appId
,
previousVersionId
,
previousVersionId
,
}:
{
appId
:
number
;
previousVersionId
:
string
},
}:
{
appId
:
number
;
previousVersionId
:
string
},
)
=>
{
)
:
Promise
<
void
>
=>
{
return
withLock
(
appId
,
async
()
=>
{
return
withLock
(
appId
,
async
()
=>
{
const
app
=
await
db
.
query
.
apps
.
findFirst
({
const
app
=
await
db
.
query
.
apps
.
findFirst
({
where
:
eq
(
apps
.
id
,
appId
),
where
:
eq
(
apps
.
id
,
appId
),
...
@@ -205,8 +205,6 @@ export function registerVersionHandlers() {
...
@@ -205,8 +205,6 @@ export function registerVersionHandlers() {
);
);
}
}
}
}
return
{
success
:
true
};
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
logger
.
error
(
logger
.
error
(
`Error reverting to version
${
previousVersionId
}
for app
${
appId
}
:`
,
`Error reverting to version
${
previousVersionId
}
for app
${
appId
}
:`
,
...
@@ -220,7 +218,10 @@ export function registerVersionHandlers() {
...
@@ -220,7 +218,10 @@ export function registerVersionHandlers() {
ipcMain
.
handle
(
ipcMain
.
handle
(
"checkout-version"
,
"checkout-version"
,
async
(
_
,
{
appId
,
versionId
}:
{
appId
:
number
;
versionId
:
string
})
=>
{
async
(
_
,
{
appId
,
versionId
}:
{
appId
:
number
;
versionId
:
string
},
):
Promise
<
void
>
=>
{
return
withLock
(
appId
,
async
()
=>
{
return
withLock
(
appId
,
async
()
=>
{
const
app
=
await
db
.
query
.
apps
.
findFirst
({
const
app
=
await
db
.
query
.
apps
.
findFirst
({
where
:
eq
(
apps
.
id
,
appId
),
where
:
eq
(
apps
.
id
,
appId
),
...
@@ -240,8 +241,6 @@ export function registerVersionHandlers() {
...
@@ -240,8 +241,6 @@ export function registerVersionHandlers() {
ref
:
versionId
,
ref
:
versionId
,
force
:
true
,
force
:
true
,
});
});
return
{
success
:
true
};
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
logger
.
error
(
logger
.
error
(
`Error checking out version
${
versionId
}
for app
${
appId
}
:`
,
`Error checking out version
${
versionId
}
for app
${
appId
}
:`
,
...
...
src/ipc/ipc_client.ts
浏览文件 @
c203b1d0
...
@@ -458,17 +458,11 @@ export class IpcClient {
...
@@ -458,17 +458,11 @@ export class IpcClient {
}:
{
}:
{
appId
:
number
;
appId
:
number
;
previousVersionId
:
string
;
previousVersionId
:
string
;
}):
Promise
<
{
success
:
boolean
}
>
{
}):
Promise
<
void
>
{
try
{
await
this
.
ipcRenderer
.
invoke
(
"revert-version"
,
{
const
result
=
await
this
.
ipcRenderer
.
invoke
(
"revert-version"
,
{
appId
,
appId
,
previousVersionId
,
previousVersionId
,
});
});
return
result
;
}
catch
(
error
)
{
showError
(
error
);
throw
error
;
}
}
}
// Checkout a specific version without creating a revert commit
// Checkout a specific version without creating a revert commit
...
@@ -478,17 +472,11 @@ export class IpcClient {
...
@@ -478,17 +472,11 @@ export class IpcClient {
}:
{
}:
{
appId
:
number
;
appId
:
number
;
versionId
:
string
;
versionId
:
string
;
}):
Promise
<
{
success
:
boolean
}
>
{
}):
Promise
<
void
>
{
try
{
await
this
.
ipcRenderer
.
invoke
(
"checkout-version"
,
{
const
result
=
await
this
.
ipcRenderer
.
invoke
(
"checkout-version"
,
{
appId
,
appId
,
versionId
,
versionId
,
});
});
return
result
;
}
catch
(
error
)
{
showError
(
error
);
throw
error
;
}
}
}
// Get the current branch of an app
// Get the current branch of an app
...
...
src/lib/assert.ts
0 → 100644
浏览文件 @
c203b1d0
export
function
assertExists
<
T
>
(
value
:
T
,
message
:
string
,
):
asserts
value
is
NonNullable
<
T
>
{
if
(
value
===
undefined
||
value
===
null
)
{
throw
new
Error
(
message
);
}
}
src/renderer.tsx
浏览文件 @
c203b1d0
...
@@ -9,6 +9,7 @@ import {
...
@@ -9,6 +9,7 @@ import {
QueryCache
,
QueryCache
,
QueryClient
,
QueryClient
,
QueryClientProvider
,
QueryClientProvider
,
MutationCache
,
}
from
"@tanstack/react-query"
;
}
from
"@tanstack/react-query"
;
import
{
showError
}
from
"./lib/toast"
;
import
{
showError
}
from
"./lib/toast"
;
...
@@ -39,6 +40,13 @@ const queryClient = new QueryClient({
...
@@ -39,6 +40,13 @@ const queryClient = new QueryClient({
}
}
},
},
}),
}),
mutationCache
:
new
MutationCache
({
onError
:
(
error
,
_variables
,
_context
,
mutation
)
=>
{
if
(
mutation
.
meta
?.
showErrorToast
)
{
showError
(
error
);
}
},
}),
});
});
const
posthogClient
=
posthog
.
init
(
const
posthogClient
=
posthog
.
init
(
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论