Migrate to SQLite for Internal Launcher Data (#1300)

* initial migration

* barebones profiles

* Finish profiles

* Add back file watcher

* UI support progress

* Finish most of cache

* Fix options page

* Fix forge, finish modrinth auth

* Accounts, process cache

* Run SQLX prepare

* Finish

* Run lint + actions

* Fix version to be compat with windows

* fix lint

* actually fix lint

* actually fix lint again
This commit is contained in:
Geometrically
2024-07-24 11:03:19 -07:00
committed by GitHub
parent 90f74427d9
commit 49a20a303a
156 changed files with 9208 additions and 8547 deletions

View File

@@ -10,6 +10,7 @@ import {
NavRow,
Card,
SearchFilter,
Avatar,
} from '@modrinth/ui'
import { formatCategoryHeader, formatCategory } from '@modrinth/utils'
import Multiselect from 'vue-multiselect'
@@ -17,29 +18,22 @@ import { handleError } from '@/store/state'
import { useBreadcrumbs } from '@/store/breadcrumbs'
import { get_categories, get_loaders, get_game_versions } from '@/helpers/tags'
import { useRoute, useRouter } from 'vue-router'
import { Avatar } from '@modrinth/ui'
import SearchCard from '@/components/ui/SearchCard.vue'
import InstallConfirmModal from '@/components/ui/InstallConfirmModal.vue'
import ModInstallModal from '@/components/ui/ModInstallModal.vue'
import SplashScreen from '@/components/ui/SplashScreen.vue'
import IncompatibilityWarningModal from '@/components/ui/IncompatibilityWarningModal.vue'
import { useFetch } from '@/helpers/fetch.js'
import { check_installed, get, get as getInstance } from '@/helpers/profile.js'
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile.js'
import { convertFileSrc } from '@tauri-apps/api/tauri'
import { isOffline } from '@/helpers/utils'
import { offline_listener } from '@/helpers/events'
import { get_search_results } from '@/helpers/cache.js'
import { debounce } from '@/helpers/utils.js'
const router = useRouter()
const route = useRoute()
const offline = ref(await isOffline())
const unlistenOffline = await offline_listener((b) => {
offline.value = b
const offline = ref(!navigator.onLine)
window.addEventListener('offline', () => {
offline.value = true
})
window.addEventListener('online', () => {
offline.value = false
})
const confirmModal = ref(null)
const modInstallModal = ref(null)
const incompatibilityWarningModal = ref(null)
const breadcrumbs = useBreadcrumbs()
breadcrumbs.setContext({ name: 'Browse', link: route.path, query: route.query })
@@ -65,6 +59,7 @@ const maxResults = ref(20)
const currentPage = ref(1)
const projectType = ref(route.params.projectType)
const instanceContext = ref(null)
const instanceProjects = ref(null)
const ignoreInstanceLoaders = ref(false)
const ignoreInstanceGameVersions = ref(false)
@@ -88,7 +83,10 @@ if (route.query.il) {
ignoreInstanceLoaders.value = route.query.il === 'true'
}
if (route.query.i) {
instanceContext.value = await getInstance(route.query.i, true)
;[instanceContext.value, instanceProjects.value] = await Promise.all([
getInstance(route.query.i).catch(handleError),
getInstanceProjects(route.query.i).catch(handleError),
])
}
if (route.query.q) {
query.value = route.query.q
@@ -144,18 +142,16 @@ if (route.query.ai) {
}
async function refreshSearch() {
const base = 'https://api.modrinth.com/v2/'
const params = [`limit=${maxResults.value}`, `index=${sortType.value.name}`]
if (query.value.length > 0) {
params.push(`query=${query.value.replace(/ /g, '+')}`)
}
if (instanceContext.value) {
if (!ignoreInstanceLoaders.value && projectType.value === 'mod') {
orFacets.value = [`categories:${encodeURIComponent(instanceContext.value.metadata.loader)}`]
orFacets.value = [`categories:${encodeURIComponent(instanceContext.value.loader)}`]
}
if (!ignoreInstanceGameVersions.value) {
selectedVersions.value = [instanceContext.value.metadata.game_version]
selectedVersions.value = [instanceContext.value.game_version]
}
}
if (
@@ -224,13 +220,11 @@ async function refreshSearch() {
}
if (hideAlreadyInstalled.value) {
const installedMods = await get(instanceContext.value.path, false).then((x) =>
Object.values(x.projects)
.filter((x) => x.metadata.project)
.map((x) => x.metadata.project.id),
)
const installedMods = Object.values(instanceProjects.value)
.filter((x) => x.metadata)
.map((x) => x.metadata.project_id)
installedMods.map((x) => [`project_id != ${x}`]).forEach((x) => formattedFacets.push(x))
console.log(`facets=${JSON.stringify(formattedFacets)}`)
}
params.push(`facets=${JSON.stringify(formattedFacets)}`)
@@ -246,24 +240,24 @@ async function refreshSearch() {
}
}
let val = `${base}${url}`
let rawResults = await useFetch(val, 'search results', offline.value)
let rawResults = await get_search_results(`?${url}`)
if (!rawResults) {
rawResults = {
hits: [],
total_hits: 0,
limit: 1,
result: {
hits: [],
total_hits: 0,
limit: 1,
},
}
}
if (instanceContext.value) {
for (val of rawResults.hits) {
val.installed = await check_installed(instanceContext.value.path, val.project_id).then(
(x) => (val.installed = x),
for (const val of rawResults.result.hits) {
val.installed = Object.values(instanceProjects.value).some(
(x) => x.metadata && x.metadata.project_id === val.project_id,
)
}
}
results.value = rawResults
results.value = rawResults.result
}
async function onSearchChange(newPageNumber) {
@@ -282,6 +276,8 @@ async function onSearchChange(newPageNumber) {
}
}
const debouncedSearchChange = debounce(() => onSearchChange(1), 200)
const searchWrapper = ref(null)
async function onSearchChangeToTop(newPageNumber) {
await onSearchChange(newPageNumber)
@@ -505,13 +501,13 @@ const selectableProjectTypes = computed(() => {
if (instanceContext.value) {
if (
availableGameVersions.value.findIndex(
(x) => x.version === instanceContext.value.metadata.game_version,
(x) => x.version === instanceContext.value.game_version,
) <= availableGameVersions.value.findIndex((x) => x.version === '1.13')
) {
values.unshift({ label: 'Data Packs', href: `/browse/datapack` })
}
if (instanceContext.value.metadata.loader !== 'vanilla') {
if (instanceContext.value.loader !== 'vanilla') {
values.unshift({ label: 'Mods', href: '/browse/mod' })
}
} else {
@@ -528,8 +524,6 @@ const showVersions = computed(
)
const isModProject = computed(() => ['modpack', 'mod'].includes(projectType.value))
onUnmounted(() => unlistenOffline())
</script>
<template>
@@ -538,27 +532,19 @@ onUnmounted(() => unlistenOffline())
<Card v-if="instanceContext" class="small-instance">
<router-link :to="`/instance/${encodeURIComponent(instanceContext.path)}`" class="instance">
<Avatar
:src="
!instanceContext.metadata.icon ||
(instanceContext.metadata.icon && instanceContext.metadata.icon.startsWith('http'))
? instanceContext.metadata.icon
: convertFileSrc(instanceContext.metadata.icon)
"
:alt="instanceContext.metadata.name"
:src="instanceContext.icon_path ? convertFileSrc(instanceContext.icon_path) : null"
:alt="instanceContext.name"
size="sm"
/>
<div class="small-instance_info">
<span class="title">{{
instanceContext.metadata.name.length > 20
? instanceContext.metadata.name.substring(0, 20) + '...'
: instanceContext.metadata.name
instanceContext.name.length > 20
? instanceContext.name.substring(0, 20) + '...'
: instanceContext.name
}}</span>
<span>
{{
instanceContext.metadata.loader.charAt(0).toUpperCase() +
instanceContext.metadata.loader.slice(1)
}}
{{ instanceContext.metadata.game_version }}
{{ instanceContext.loader.charAt(0).toUpperCase() + instanceContext.loader.slice(1) }}
{{ instanceContext.game_version }}
</span>
</div>
</router-link>
@@ -598,7 +584,10 @@ onUnmounted(() => unlistenOffline())
>
<ClearIcon /> Clear filters
</Button>
<div v-if="isModProject || projectType === 'shader'" class="loaders">
<div
v-if="(isModProject && ignoreInstanceLoaders) || projectType === 'shader'"
class="loaders"
>
<h2>Loaders</h2>
<div v-for="loader in filteredLoaders" :key="loader">
<SearchFilter
@@ -693,9 +682,10 @@ onUnmounted(() => unlistenOffline())
<input
v-model="query"
autocomplete="off"
spellcheck="false"
type="text"
:placeholder="`Search ${projectType}s...`"
@input="onSearchChange(1)"
@input="debouncedSearchChange()"
/>
<Button class="r-btn" @click="() => clearSearch()">
<XIcon />
@@ -752,9 +742,6 @@ onUnmounted(() => unlistenOffline())
loader.supported_project_types?.includes(projectType),
),
]"
:confirm-modal="confirmModal"
:mod-install-modal="modInstallModal"
:incompatibility-warning-modal="incompatibilityWarningModal"
:installed="result.installed"
/>
</section>
@@ -768,9 +755,6 @@ onUnmounted(() => unlistenOffline())
<br />
</div>
</div>
<InstallConfirmModal ref="confirmModal" />
<ModInstallModal ref="modInstallModal" />
<IncompatibilityWarningModal ref="incompatibilityWarningModal" />
</template>
<style src="vue-multiselect/dist/vue-multiselect.css"></style>