Skip to content
This repository has been archived by the owner on Aug 3, 2024. It is now read-only.

Remove homepage projects and tags build-time caching #1200

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .github/workflows/regenerate.yml

This file was deleted.

27 changes: 27 additions & 0 deletions composables/homepage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { UseFetchOptions } from '#app'

export async function useHomepageProjects(rowsCount: number) {
const runtimeConfig = useRuntimeConfig()

const fetchOptions: UseFetchOptions<any[], any[][]> = {
baseURL: runtimeConfig.public.apiBaseUrl,
key: `homepageProjects/${rowsCount}`,
transform(homepageProjects) {
const val = Math.ceil(homepageProjects.length / rowsCount)
const result: any[][] = []
for (let i = 0; i < rowsCount; i++) {
result.push(homepageProjects.slice(val * i, val * (i + 1)))
}
return result
},
}

if (import.meta.server) {
fetchOptions.headers = {
'User-Agent': 'Knossos Server ([email protected])',
'X-Ratelimit-Key': runtimeConfig.rateLimitKey,
}
}

return await useFetch('/projects_random?count=40', fetchOptions)
}
64 changes: 1 addition & 63 deletions composables/tag.js
Original file line number Diff line number Diff line change
@@ -1,63 +1 @@
import tags from '~/generated/state.json'

export const useTags = () =>
useState('tags', () => ({
categories: tags.categories,
loaders: tags.loaders,
gameVersions: tags.gameVersions,
donationPlatforms: tags.donationPlatforms,
reportTypes: tags.reportTypes,
projectTypes: [
{
actual: 'mod',
id: 'mod',
display: 'mod',
},
{
actual: 'mod',
id: 'plugin',
display: 'plugin',
},
{
actual: 'mod',
id: 'datapack',
display: 'data pack',
},
{
actual: 'shader',
id: 'shader',
display: 'shader',
},
{
actual: 'resourcepack',
id: 'resourcepack',
display: 'resource pack',
},
{
actual: 'modpack',
id: 'modpack',
display: 'modpack',
},
],
loaderData: {
pluginLoaders: ['bukkit', 'spigot', 'paper', 'purpur', 'sponge', 'folia'],
pluginPlatformLoaders: ['bungeecord', 'waterfall', 'velocity'],
allPluginLoaders: [
'bukkit',
'spigot',
'paper',
'purpur',
'sponge',
'bungeecord',
'waterfall',
'velocity',
'folia',
],
dataPackLoaders: ['datapack'],
modLoaders: ['forge', 'fabric', 'quilt', 'liteloader', 'modloader', 'rift', 'neoforge'],
},
projectViewModes: ['list', 'grid', 'gallery'],
approvedStatuses: ['approved', 'archived', 'unlisted', 'private'],
rejectedStatuses: ['rejected', 'withheld'],
staffRoles: ['moderator', 'admin'],
}))
export const useTags = () => useNuxtApp().$tags
69 changes: 0 additions & 69 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { pathToFileURL } from 'node:url'
import svgLoader from 'vite-svg-loader'
import { resolve, basename } from 'pathe'
import { defineNuxtConfig } from 'nuxt/config'
import { $fetch } from 'ofetch'
import { globIterate } from 'glob'
import { match as matchLocale } from '@formatjs/intl-localematcher'

Expand Down Expand Up @@ -93,74 +92,6 @@ export default defineNuxtConfig({
],
},
hooks: {
async 'build:before'() {
// 30 minutes
const TTL = 30 * 60 * 1000

let state: {
lastGenerated?: string
apiUrl?: string
categories?: any[]
loaders?: any[]
gameVersions?: any[]
donationPlatforms?: any[]
reportTypes?: any[]
} = {}
let homePageProjects: any[] = []

try {
state = JSON.parse(await fs.readFile('./generated/state.json', 'utf8'))
homePageProjects = JSON.parse(await fs.readFile('./generated/homepage.json', 'utf8'))
} catch {
// File doesn't exist, create folder
await fs.mkdir('./generated', { recursive: true })
}

const API_URL = getApiUrl()

if (
// Skip regeneration if within TTL...
state.lastGenerated &&
new Date(state.lastGenerated).getTime() + TTL > new Date().getTime() &&
// ...but only if the API URL is the same
state.apiUrl === API_URL &&
homePageProjects.length !== 0
) {
return
}

state.lastGenerated = new Date().toISOString()

state.apiUrl = API_URL

const headers = {
headers: {
'user-agent': 'Knossos generator ([email protected])',
},
}

const [categories, loaders, gameVersions, donationPlatforms, reportTypes, projects] =
await Promise.all([
$fetch(`${API_URL}tag/category`, headers),
$fetch(`${API_URL}tag/loader`, headers),
$fetch(`${API_URL}tag/game_version`, headers),
$fetch(`${API_URL}tag/donation_platform`, headers),
$fetch(`${API_URL}tag/report_type`, headers),
$fetch(`${API_URL}projects_random?count=40`, headers),
])

state.categories = categories
state.loaders = loaders
state.gameVersions = gameVersions
state.donationPlatforms = donationPlatforms
state.reportTypes = reportTypes
homePageProjects = projects

await fs.writeFile('./generated/state.json', JSON.stringify(state))
await fs.writeFile('./generated/homepage.json', JSON.stringify(homePageProjects))

console.log('Tags generated!')
},
'pages:extend'(routes) {
routes.splice(
routes.findIndex((x) => x.name === 'search-searchProjectType'),
Expand Down
16 changes: 4 additions & 12 deletions pages/app.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<script setup>
import { TrashIcon, SearchIcon, BoxIcon, SendIcon, EditIcon, DownloadIcon } from 'omorphia'
import Avatar from '~/components/ui/Avatar.vue'
import homepageProjects from '~/generated/homepage.json'

import LogoAnimated from '~/components/brand/LogoAnimated.vue'
import Badge from '~/components/ui/Badge.vue'
import PrismIcon from '~/assets/images/external/prism.svg'
import ATLauncher from '~/assets/images/external/atlauncher.svg'
import CurseForge from '~/assets/images/external/curseforge.svg'
import Checkbox from '~/components/ui/Checkbox.vue'

const val = Math.ceil(homepageProjects.length / 6)
const os = ref(null)
const macValue = ref(null)
const downloadWindows = ref(null)
Expand All @@ -27,18 +26,11 @@ const macLinks = {

let downloadLauncher

const rows = shallowRef([
homepageProjects.slice(0, val),
homepageProjects.slice(val, val * 2),
homepageProjects.slice(val * 2, val * 3),
homepageProjects.slice(val * 3, val * 4),
homepageProjects.slice(val * 4, val * 5),
const [{ data: rows }, { data: launcherUpdates }] = await Promise.all([
useHomepageProjects(6),
useFetch('https://launcher-files.modrinth.com/updates.json', { key: 'launcherUpdates' }),
])

const { data: launcherUpdates } = await useAsyncData('launcherUpdates', () =>
$fetch('https://launcher-files.modrinth.com/updates.json')
)

macLinks.appleSilicon = launcherUpdates.value.platforms['darwin-aarch64'].install_urls[0]
macLinks.intel = launcherUpdates.value.platforms['darwin-x86_64'].install_urls[0]
windowsLink.value = launcherUpdates.value.platforms['windows-x86_64'].install_urls[0]
Expand Down
34 changes: 15 additions & 19 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -513,33 +513,29 @@ import PrismLauncherLogo from '~/assets/images/external/prism.svg'
import ATLauncherLogo from '~/assets/images/external/atlauncher.svg'
import Avatar from '~/components/ui/Avatar.vue'
import ProjectCard from '~/components/ui/ProjectCard.vue'
import homepageProjects from '~/generated/homepage.json'

const searchQuery = ref('better')
const sortType = ref('relevance')

const auth = await useAuth()
const tags = useTags()

const [{ data: searchProjects, refresh: updateSearchProjects }, { data: notifications }] =
await Promise.all([
useAsyncData(
'demoSearchProjects',
() => useBaseFetch(`search?limit=3&query=${searchQuery.value}&index=${sortType.value}`),
{
transform: (result) => result.hits,
}
),
useAsyncData('updatedProjects', () => useBaseFetch(`search?limit=3&query=&index=updated`), {
const [
{ data: searchProjects, refresh: updateSearchProjects },
{ data: notifications },
{ data: rows },
] = await Promise.all([
useAsyncData(
'demoSearchProjects',
() => useBaseFetch(`search?limit=3&query=${searchQuery.value}&index=${sortType.value}`),
{
transform: (result) => result.hits,
}),
])

const val = Math.ceil(homepageProjects.length / 3)
const rows = shallowRef([
homepageProjects.slice(0, val),
homepageProjects.slice(val, val * 2),
homepageProjects.slice(val * 2, val * 3),
}
),
useAsyncData('updatedProjects', () => useBaseFetch(`search?limit=3&query=&index=updated`), {
transform: (result) => result.hits,
}),
useHomepageProjects(3),
])
</script>

Expand Down
93 changes: 93 additions & 0 deletions plugins/tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { NitroFetchOptions } from 'nitropack'

export default defineNuxtPlugin(async () => {
const runtimeConfig = useRuntimeConfig()

const requestOptions: NitroFetchOptions<any, 'get'> = {
baseURL: runtimeConfig.public.apiBaseUrl,
}

if (import.meta.server) {
requestOptions.headers = {
'User-Agent': 'Knossos Server ([email protected])',
'X-Ratelimit-Key': runtimeConfig.rateLimitKey,
}
}

const { data: tags } = await useAsyncData('tags', async () => {
const [categories, loaders, gameVersions, donationPlatforms, reportTypes] = await Promise.all([
$fetch(`tag/category`, requestOptions),
$fetch(`tag/loader`, requestOptions),
$fetch(`tag/game_version`, requestOptions),
$fetch(`tag/donation_platform`, requestOptions),
$fetch(`tag/report_type`, requestOptions),
])

return {
categories,
loaders,
gameVersions,
donationPlatforms,
reportTypes,
projectTypes: [
{
actual: 'mod',
id: 'mod',
display: 'mod',
},
{
actual: 'mod',
id: 'plugin',
display: 'plugin',
},
{
actual: 'mod',
id: 'datapack',
display: 'data pack',
},
{
actual: 'shader',
id: 'shader',
display: 'shader',
},
{
actual: 'resourcepack',
id: 'resourcepack',
display: 'resource pack',
},
{
actual: 'modpack',
id: 'modpack',
display: 'modpack',
},
],
loaderData: {
pluginLoaders: ['bukkit', 'spigot', 'paper', 'purpur', 'sponge', 'folia'],
pluginPlatformLoaders: ['bungeecord', 'waterfall', 'velocity'],
allPluginLoaders: [
'bukkit',
'spigot',
'paper',
'purpur',
'sponge',
'bungeecord',
'waterfall',
'velocity',
'folia',
],
dataPackLoaders: ['datapack'],
modLoaders: ['forge', 'fabric', 'quilt', 'liteloader', 'modloader', 'rift', 'neoforge'],
},
projectViewModes: ['list', 'grid', 'gallery'],
approvedStatuses: ['approved', 'archived', 'unlisted', 'private'],
rejectedStatuses: ['rejected', 'withheld'],
staffRoles: ['moderator', 'admin'],
}
})

return {
provide: {
tags,
},
}
})