Skip to content

Commit

Permalink
fix: Revalidate instance files before launch
Browse files Browse the repository at this point in the history
  • Loading branch information
ci010 committed Jan 3, 2024
1 parent 81e9a6d commit 61f8915
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 26 deletions.
17 changes: 15 additions & 2 deletions xmcl-keystone-ui/src/composables/curseforgeInstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useNotifier } from './notifier'
import { useResourceUrisDiscovery } from './resources'
import { useService } from './service'
import { useSWRVModel } from './swrv'
import { kInstanceFiles } from './instanceFiles'

export const kCurseforgeInstall: InjectionKey<ReturnType<typeof useCurseforgeInstall>> = Symbol('CurseforgeInstall')

Expand Down Expand Up @@ -116,12 +117,14 @@ export function useCurseforgeInstall(modId: Ref<number>, files: Ref<Pick<File, '
}

export function useCurseforgeInstallModpack(icon: Ref<string | undefined>) {
const { instances } = injection(kInstances)
const { instances, selectedInstance } = injection(kInstances)
const { getModpackInstallFiles } = useService(ModpackServiceKey)
const { installInstanceFiles } = useService(InstanceInstallServiceKey)
const { createInstance } = useService(InstanceServiceKey)
const { installFile } = useService(CurseForgeServiceKey)
const { install, mutate } = injection(kInstanceFiles)
const { fix } = injection(kInstanceVersionDiagnose)
const { currentRoute, push } = useRouter()
const installModpack = async (f: File) => {
const result = await installFile({ file: f, type: 'modpacks', icon: icon.value })
const resource = result.resource
Expand All @@ -133,11 +136,21 @@ export function useCurseforgeInstallModpack(icon: Ref<string | undefined>) {
...config,
name,
})
selectedInstance.value = path
if (currentRoute.path !== '/') {
push('/')
}
const files = await getModpackInstallFiles(resource.path)
await installInstanceFiles({
path,
files,
}).catch(() => { })
}).catch(() => {
if (selectedInstance.value === path) {
return install()
}
}).finall(() => {
mutate()
})
await fix()
}
return installModpack
Expand Down
24 changes: 13 additions & 11 deletions xmcl-keystone-ui/src/composables/instanceFiles.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { InstanceFile, InstanceInstallServiceKey } from '@xmcl/runtime-api'
import { Ref, InjectionKey } from 'vue'
import { useRefreshable } from './refreshable'
import useSWRV from 'swrv'
import { InjectionKey, Ref } from 'vue'
import { useService } from './service'
import debounce from 'lodash.debounce'

export const kInstanceFiles: InjectionKey<ReturnType<typeof useInstanceFiles>> = Symbol('InstanceFiles')

Expand All @@ -10,7 +11,7 @@ export function useInstanceFiles(instancePath: Ref<string>) {
const { checkInstanceInstall, installInstanceFiles } = useService(InstanceInstallServiceKey)

let abortController = new AbortController()
const { refresh, error, refreshing } = useRefreshable(async () => {
const { mutate, error, isValidating } = useSWRV(computed(() => instancePath.value), async () => {
if (!instancePath.value) { return }
abortController.abort()
abortController = new AbortController()
Expand All @@ -21,26 +22,27 @@ export function useInstanceFiles(instancePath: Ref<string>) {
files.value = result
})

const _validating = ref(false)
const update = debounce(() => {
_validating.value = isValidating.value
}, 400)
watch(isValidating, update)

async function install() {
if (files.value.length > 0) {
// has unfinished files
try {
await installInstanceFiles({ files: files.value, path: instancePath.value })
} finally {
refresh()
mutate()
}
} else {
refresh()
}
}

onMounted(() => refresh())
watch(instancePath, () => refresh())

return {
files,
refreshing,
refresh,
isValidating: _validating,
mutate,
error,
install,
}
Expand Down
5 changes: 1 addition & 4 deletions xmcl-keystone-ui/src/composables/instanceVersionDiagnose.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { DiagnoseServiceKey, InstallServiceKey, InstanceServiceKey, LocalVersionHeader, ReadWriteLock, RuntimeVersions, VersionMetadataServiceKey, getExpectVersion } from '@xmcl/runtime-api'
import { DiagnoseServiceKey, InstallServiceKey, InstanceServiceKey, LocalVersionHeader, ReadWriteLock, RuntimeVersions, getExpectVersion } from '@xmcl/runtime-api'
import { InjectionKey, Ref } from 'vue'
import { InstanceResolveVersion } from './instanceVersion'
import { useInstanceVersionInstall } from './instanceVersionInstall'
import { LaunchMenuItem } from './launchButton'
import { useService } from './service'
import { kSWRVConfig } from './swrvConfig'

export const kInstanceVersionDiagnose: InjectionKey<ReturnType<typeof useInstanceVersionDiagnose>> = Symbol('InstanceVersionDiagnose')

Expand All @@ -21,8 +20,6 @@ export function useInstanceVersionDiagnose(path: Ref<string>, runtime: Ref<Runti
let pendingFix = false

const lock = new ReadWriteLock()
const serv = useService(VersionMetadataServiceKey)
const config = inject(kSWRVConfig)

const loading = ref(false)

Expand Down
7 changes: 4 additions & 3 deletions xmcl-keystone-ui/src/composables/launchButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ export interface LaunchMenuItem {

export function useLaunchButton() {
const { show: showLaunchStatusDialog } = useDialog(LaunchStatusDialogKey)
const { show: showMultiInstanceDialog } = useDialog('multi-instance-launch')

const { path } = injection(kInstance)
const { issues: versionIssues, fix: fixVersionIssues, loading: loadingVersionIssues } = injection(kInstanceVersionDiagnose)
const { issue: javaIssue, fix: fixJavaIssue } = injection(kInstanceJavaDiagnose)
const { issue: filesIssue, fix: fixInstanceFileIssue } = injection(kInstanceFilesDiagnose)
const { issue: userIssue, fix: fixUserIssue } = injection(kUserDiagnose)
const { status, pause, resume } = injection(kLaunchTask)
const { refreshing: refreshingFiles } = injection(kInstanceFiles)
const { isValidating: refreshingFiles, mutate } = injection(kInstanceFiles)
const { isValidating: isRefreshingVersion } = injection(kInstanceVersion)
const { launch, launching, count, kill } = injection(kInstanceLaunch)

Expand Down Expand Up @@ -125,7 +124,9 @@ export function useLaunchButton() {
color: !javaIssue.value ? 'primary' : 'primary darken-1',
leftIcon: 'play_arrow',
menu: javaIssue.value ? [javaIssue.value] : [],
onClick: () => {
onClick: async () => {
await mutate().catch(() => {})
await fixInstanceFileIssue()
launch()
showLaunchStatusDialog(false)
},
Expand Down
17 changes: 14 additions & 3 deletions xmcl-keystone-ui/src/views/StoreProjectModrinth.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import StoreProjectBase, { StoreProject } from '@/components/StoreProject.vue'
import { StoreProjectVersion } from '@/components/StoreProjectInstallVersionDialog.vue'
import { TeamMember } from '@/components/StoreProjectMembers.vue'
import { useService } from '@/composables'
import { kInstanceFiles } from '@/composables/instanceFiles'
import { kInstanceVersionDiagnose } from '@/composables/instanceVersionDiagnose'
import { useInstanceVersionInstall } from '@/composables/instanceVersionInstall'
import { kInstances } from '@/composables/instances'
import { useMarkdown } from '@/composables/markdown'
import { useModrinthTags } from '@/composables/modrinth'
Expand All @@ -13,7 +13,6 @@ import { useModrinthVersions } from '@/composables/modrinthVersions'
import { usePresence } from '@/composables/presence'
import { kSWRVConfig } from '@/composables/swrvConfig'
import { useTasks } from '@/composables/task'
import { kLocalVersions } from '@/composables/versionLocal'
import { clientModrinthV2 } from '@/util/clients'
import { injection } from '@/util/inject'
import { generateDistinctName } from '@/util/instanceName'
Expand Down Expand Up @@ -140,7 +139,9 @@ const { getModpackInstallFiles } = useService(ModpackServiceKey)
const { installInstanceFiles } = useService(InstanceInstallServiceKey)
const { createInstance } = useService(InstanceServiceKey)
const { installVersion } = useService(ModrinthServiceKey)
const { install, mutate } = injection(kInstanceFiles)
const { fix } = injection(kInstanceVersionDiagnose)
const { currentRoute } = useRouter()
const installModpack = async (v: ProjectVersion) => {
const result = await installVersion({ version: v, icon: project.value?.iconUrl })
const resource = result.resources[0]
Expand All @@ -152,11 +153,21 @@ const installModpack = async (v: ProjectVersion) => {
...config,
name,
})
selectedInstance.value = path
if (currentRoute.path !== '/') {
push('/')
}
const files = await getModpackInstallFiles(resource.path)
await installInstanceFiles({
path,
files,
}).catch(console.error)
}).catch(() => {
if (selectedInstance.value === path) {
return install()
}
}).finally(() => {
mutate()
})
fix()
}
Expand Down
4 changes: 1 addition & 3 deletions xmcl-runtime/instanceIO/instanceInstall.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { ModrinthV2Client } from '@xmcl/modrinth'
import { InstanceFile, ResourceMetadata } from '@xmcl/runtime-api'
import { InstanceFile } from '@xmcl/runtime-api'
import { writeFile } from 'atomically'
import { unlink } from 'fs/promises'
import { join } from 'path'
import { ResourceService } from '~/resource'

export type RequiredPick<T, K extends keyof T> = T & Required<Pick<T, K>>

Expand Down

0 comments on commit 61f8915

Please sign in to comment.