Skip to content

Commit

Permalink
refactor: Move the curseforge using swrv and adjust mod/resourcepack …
Browse files Browse the repository at this point in the history
…card navigation
  • Loading branch information
ci010 committed May 3, 2023
1 parent 367103e commit cc5cb87
Show file tree
Hide file tree
Showing 29 changed files with 401 additions and 321 deletions.
7 changes: 6 additions & 1 deletion xmcl-electron-app/main/Controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ export default class Controller implements LauncherAppController {
}

restoredSession.webRequest.onHeadersReceived((detail, cb) => {
if (detail.responseHeaders /* && detail.resourceType === 'image' */) {
if (detail.responseHeaders &&
!detail.responseHeaders['access-control-allow-origin'] &&
!detail.responseHeaders['Access-Control-Allow-Origin']) {
detail.responseHeaders['access-control-allow-origin'] = ['*']
}

Expand All @@ -223,6 +225,9 @@ export default class Controller implements LauncherAppController {
}).catch(() => {
cb({ requestHeaders: detail.requestHeaders })
})
} else if (detail.url.startsWith('https://api.curseforge.com')) {
detail.requestHeaders['x-api-key'] = process.env.CURSEFORGE_API_KEY || ''
cb({ requestHeaders: detail.requestHeaders })
} else {
cb({ requestHeaders: detail.requestHeaders })
}
Expand Down
130 changes: 60 additions & 70 deletions xmcl-keystone-ui/src/composables/curseforge.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { computed, InjectionKey, onMounted, reactive, Ref, ref, toRefs, watch } from 'vue'
import { File, FileModLoaderType, Mod, ModCategory, ModsSearchSortField } from '@xmcl/curseforge'
import { CurseForgeServiceKey, Persisted, ProjectType, Resource, ResourceServiceKey } from '@xmcl/runtime-api'
import { useRefreshable, useService, useServiceBusy } from '@/composables'
import { CurseforgeV1Client, File, FileModLoaderType, Mod, ModsSearchSortField } from '@xmcl/curseforge'
import useSWRV from 'swrv'
import { computed, InjectionKey, reactive, Ref, ref, toRefs, watch } from 'vue'
import { kSWRVConfig, useOverrideSWRVConfig } from './swrvConfig'

interface CurseforgeProps {
type: string
Expand All @@ -15,12 +15,13 @@ interface CurseforgeProps {
from: string
}

export const client = new CurseforgeV1Client('', {})

/**
* Hook to return the controller of curseforge preview page. Navigating the curseforge projects.
*/
export function useCurseforge(props: CurseforgeProps) {
const router = useRouter()
const { searchProjects } = useService(CurseForgeServiceKey)
const pageSize = 10

const currentType = computed({
Expand Down Expand Up @@ -91,29 +92,33 @@ export function useCurseforge(props: CurseforgeProps) {
projects: [] as Mod[],
})
const index = computed(() => (currentPage.value - 1) * pageSize)
const { refresh, refreshing, error } = useRefreshable(async function refresh() {
const { data: result, pagination } = await searchProjects({
pageSize,
index: index.value,
classId: currentSectionId.value,
sortField: currentSort.value,
gameVersion: currentVersion.value,
categoryId: categoryId.value,
searchFilter: currentKeyword.value,
})
data.totalCount = pagination.totalCount
data.projects = Object.freeze(result) as any
data.pages = Math.floor(data.totalCount / pageSize)
data.projects.forEach(p => Object.freeze(p))
data.projects.forEach(p => Object.freeze(p.categories))
})
watch([currentPage, currentSort, currentVersion, currentKeyword, currentCategory, currentType], () => {
refresh()
const { mutate, isValidating, error, data: _data } = useSWRV(
computed(() => `/curseforge/search?index=${index.value}&classId=${currentSectionId.value}&sortField=${currentSort.value}&gameVersion=${currentVersion.value}&categoryId=${categoryId.value}&searchFilter=${currentKeyword.value}`),
async () => {
const result = await client.searchMods({
pageSize,
index: index.value,
classId: currentSectionId.value,
sortField: currentSort.value,
gameVersion: currentVersion.value,
categoryId: categoryId.value,
searchFilter: currentKeyword.value,
})
return markRaw(result)
}, useOverrideSWRVConfig({
ttl: 30 * 1000,
}))

watch(_data, (v) => {
if (v) {
data.projects = markRaw(v.data)
data.totalCount = v.pagination.totalCount
data.pages = Math.ceil(v.pagination.totalCount / pageSize)
}
})
onMounted(() => { refresh() })
return {
...toRefs(data),
refreshing,
refreshing: isValidating,
error,
categoryId,
currentSort,
Expand All @@ -122,7 +127,7 @@ export function useCurseforge(props: CurseforgeProps) {
currentPage,
currentCategory,
currentType,
refresh,
refresh: mutate,
}
}

Expand All @@ -131,7 +136,6 @@ export function useCurseforge(props: CurseforgeProps) {
* @param projectId The project id
*/
export function useCurseforgeProjectFiles(projectId: Ref<number>) {
const { getModFiles } = useService(CurseForgeServiceKey)
const files = inject(kCurseforgeFiles, ref([]))
const data = shallowReactive({
index: 0,
Expand All @@ -140,21 +144,24 @@ export function useCurseforgeProjectFiles(projectId: Ref<number>) {
gameVersion: undefined as string | undefined,
modLoaderType: undefined as FileModLoaderType | undefined,
})
const { refresh, refreshing, error } = useRefreshable(async () => {
const f = await getModFiles({
modId: projectId.value,
index: data.index,
gameVersion: data.gameVersion,
pageSize: data.pageSize,
modLoaderType: data.modLoaderType,
const { mutate: refresh, isValidating: refreshing, error, data: _data } = useSWRV(
computed(() => `/curseforge/${projectId.value}/files`), async () => {
return markRaw(await client.getModFiles({
modId: projectId.value,
index: data.index,
gameVersion: data.gameVersion,
pageSize: data.pageSize,
modLoaderType: data.modLoaderType,
}))
})
files.value = markRaw(f.data)
data.index = f.pagination.index
data.pageSize = f.pagination.pageSize
data.totalCount = f.pagination.totalCount
watch(_data, (f) => {
if (f) {
files.value = markRaw(f.data)
data.index = f.pagination.index
data.pageSize = f.pagination.pageSize
data.totalCount = f.pagination.totalCount
}
})
onMounted(refresh)
watch(projectId, refresh)
return {
...toRefs(data),
files,
Expand All @@ -167,49 +174,32 @@ export function useCurseforgeProjectFiles(projectId: Ref<number>) {
export const kCurseforgeFiles: InjectionKey<Ref<File[]>> = Symbol('CurseforgeFiles')

export function useCurseforgeProjectDescription(props: { project: number }) {
const { getModDescription } = useService(CurseForgeServiceKey)
const data = reactive({
description: '',
})
const { refresh, refreshing, error } = useRefreshable(async function refresh() {
const des = await getModDescription(props.project)
data.description = des
})
const { mutate: refresh, isValidating: refreshing, error, data: description } = useSWRV(
computed(() => `/curseforge/${props.project}/description`), async () => {
return await client.getModDescription(props.project)
}, inject(kSWRVConfig))

onMounted(refresh)
watch(() => props.project, refresh)
return { ...toRefs(data), refreshing, refresh, error }
return { description, refreshing, refresh, error }
}
/**
* Hook to view the front page of the curseforge project.
* @param projectId The project id
*/
export function useCurseforgeProject(projectId: Ref<number>) {
const { getMod } = useService(CurseForgeServiceKey)
const project = ref(undefined as undefined | Mod)
const refreshing = useServiceBusy(CurseForgeServiceKey, 'getMod', projectId.toString())
const { refresh, error } = useRefreshable(async function () {
project.value = markRaw(await getMod(projectId.value))
})
onMounted(() => refresh())
watch(projectId, refresh)
const { data: project, isValidating, mutate, error } = useSWRV(computed(() => `/curseforge/${projectId.value}`), async function () {
return markRaw(await client.getMod(projectId.value))
}, inject(kSWRVConfig))
return {
refreshing,
refresh,
refreshing: isValidating,
refresh: mutate,
project,
error,
}
}

export function useCurseforgeCategories() {
const { fetchCategories } = useService(CurseForgeServiceKey)
const categories = ref([] as ModCategory[])
const refreshing = useServiceBusy(CurseForgeServiceKey, 'fetchCategories')
async function refresh() {
categories.value = await fetchCategories()
}
onMounted(() => {
refresh()
})
const { isValidating: refreshing, mutate: refresh, data: categories } = useSWRV('/curseforge/categories', async () => {
return markRaw(await client.getCategories())
}, inject(kSWRVConfig))
return { categories, refreshing, refresh }
}
24 changes: 7 additions & 17 deletions xmcl-keystone-ui/src/composables/curseforgeChangelog.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import { CurseForgeServiceKey } from '@xmcl/runtime-api'
import useSWRV from 'swrv'
import { Ref } from 'vue'
import { useRefreshable } from './refreshable'
import { useService } from './service'
import { client } from './curseforge'
import { kSWRVConfig } from './swrvConfig'

export function useCurseforgeChangelog(modId: Ref<number>, fileId: Ref<number | undefined>) {
const { getFileChangelog } = useService(CurseForgeServiceKey)
const changelog = ref('')
const { refresh, refreshing } = useRefreshable(async () => {
const id = fileId.value
if (!id) {
changelog.value = ''
} else {
changelog.value = await getFileChangelog({ modId: modId.value, id: id })
}
})
onMounted(refresh)
watch([modId, fileId], refresh)
const { data: changelog } = useSWRV(
computed(() => fileId.value ? `/cureforge/${modId.value}/${fileId.value}/changelog` : undefined),
async () => client.getFileChangelog(modId.value, fileId.value!),
inject(kSWRVConfig))
return {
changelog,
refresh,
refreshing,
}
}
26 changes: 0 additions & 26 deletions xmcl-keystone-ui/src/composables/curseforgeRoute.ts

This file was deleted.

1 change: 1 addition & 0 deletions xmcl-keystone-ui/src/composables/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function useDialogModel(): DialogModel {
const model = ref({ dialog: '', parameter: undefined })
const channel = new BroadcastChannel('dialog')
channel.addEventListener('message', (e) => {
console.log(e)
if (e.data.dialog === model.value.dialog) return
model.value = e.data
})
Expand Down
16 changes: 5 additions & 11 deletions xmcl-keystone-ui/src/composables/ftb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ import { FTBClient } from '@/util/ftbClient'
import useSWRV from 'swrv'
import LocalStorageCache from 'swrv/dist/cache/adapters/localStorage'
import { LocalStroageCache } from '@/util/localStorageCache'
import { kSWRVConfig } from './swrvConfig'

interface FeedTheBeastProps {
keyword?: string
}

export function useClient() {

}

export function useFeedTheBeast(props: FeedTheBeastProps) {
const router = useRouter()

Expand All @@ -26,7 +23,7 @@ export function useFeedTheBeast(props: FeedTheBeastProps) {

const { data, isValidating: refreshing } = useSWRV(computed(() => `/ftb?keyword=${currentKeyword.value}`), async () => {
return !currentKeyword.value ? await client.getFeaturedModpacks() : await client.searchModpacks({ keyword: currentKeyword.value })
}, { cache })
}, inject(kSWRVConfig))

return {
data,
Expand All @@ -37,7 +34,7 @@ export function useFeedTheBeast(props: FeedTheBeastProps) {

export function useFeedTheBeastProject(id: Ref<number>) {
const { data: manifest, error, isValidating: refreshing, mutate } = useSWRV(computed(() => `/ftb/${id.value}`),
() => client.getModpackManifest(id.value), { cache })
() => client.getModpackManifest(id.value), inject(kSWRVConfig))

return {
manifest,
Expand All @@ -46,15 +43,12 @@ export function useFeedTheBeastProject(id: Ref<number>) {
}
}
const client = new FTBClient()
const cache = new LocalStroageCache('/cache')

export function useFeedTheBeastChangelog(version: Ref<{ id: number; version: FTBVersion }>) {
const { data, error, isValidating } = useSWRV(computed(() => `/ftb/${version.value.id}/${version.value.version.id}/changelog`), () => client.getModpackVersionChangelog({
modpack: version.value.id,
version: version.value.version,
}), {
cache,
})
}), inject(kSWRVConfig))
return {
refreshing: isValidating,
changelog: data,
Expand All @@ -68,7 +62,7 @@ export function useFeedTheBeastProjectVersion(project: Ref<number>, version: Ref
modpack: project.value,
version: version.value,
})
}, { cache })
}, inject(kSWRVConfig))

return {
refreshing,
Expand Down

0 comments on commit cc5cb87

Please sign in to comment.