mirror of
https://github.com/HangarMC/Hangar.git
synced 2024-12-27 07:03:26 +08:00
remove tons of warnings and hydration errors, speed up page loading
This commit is contained in:
parent
0381cc4ce4
commit
c1294e723e
@ -78,6 +78,7 @@
|
||||
"node-fetch": "^3.2.4",
|
||||
"pnpm": "^7.0.1",
|
||||
"prettier": "^2.6.2",
|
||||
"regenerator-runtime": "^0.13.9",
|
||||
"sass": "^1.51.0",
|
||||
"typescript": "^4.6.4",
|
||||
"unplugin-auto-import": "^0.7.1",
|
||||
|
@ -55,6 +55,7 @@ specifiers:
|
||||
prettier: ^2.6.2
|
||||
prism-theme-vars: ^0.2.2
|
||||
qs: ^6.10.3
|
||||
regenerator-runtime: ^0.13.9
|
||||
sass: ^1.51.0
|
||||
swagger-ui-dist: ^4.10.3
|
||||
typescript: ^4.6.4
|
||||
@ -134,6 +135,7 @@ devDependencies:
|
||||
node-fetch: 3.2.4
|
||||
pnpm: 7.0.1
|
||||
prettier: 2.6.2
|
||||
regenerator-runtime: 0.13.9
|
||||
sass: 1.51.0
|
||||
typescript: 4.6.4
|
||||
unplugin-auto-import: 0.7.1_utbicujaitsyfhhenhpcxjwwzu
|
||||
@ -434,7 +436,6 @@ packages:
|
||||
/@babel/helper-validator-identifier/7.16.7:
|
||||
resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
dev: true
|
||||
|
||||
/@babel/helper-validator-option/7.16.7:
|
||||
resolution: {integrity: sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==}
|
||||
@ -477,12 +478,16 @@ packages:
|
||||
resolution: {integrity: sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.17.0
|
||||
dev: true
|
||||
|
||||
/@babel/parser/7.17.8:
|
||||
resolution: {integrity: sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@babel/types': 7.17.0
|
||||
|
||||
/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.16.7_@babel+core@7.17.8:
|
||||
resolution: {integrity: sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg==}
|
||||
@ -1315,7 +1320,6 @@ packages:
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.16.7
|
||||
to-fast-properties: 2.0.0
|
||||
dev: true
|
||||
|
||||
/@eslint/eslintrc/0.4.3:
|
||||
resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==}
|
||||
@ -1943,15 +1947,19 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
|
||||
eslint-plugin-vue: ^8.0.1
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/eslint-plugin': 5.16.0_jqncz736ernh47yeh2d4pwt2h4
|
||||
'@typescript-eslint/parser': 5.16.0_t725usgvqspm5woeqpaxbfp2qu
|
||||
eslint: 8.14.0
|
||||
eslint-plugin-vue: 8.7.1_eslint@8.14.0
|
||||
typescript: 4.6.4
|
||||
vue-eslint-parser: 8.3.0_eslint@8.14.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
/@vue/reactivity-transform/3.2.33:
|
||||
@ -2543,6 +2551,8 @@ packages:
|
||||
finalhandler: 1.1.2
|
||||
parseurl: 1.3.3
|
||||
utils-merge: 1.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/convert-source-map/1.8.0:
|
||||
@ -2606,11 +2616,21 @@ packages:
|
||||
|
||||
/debug/2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
|
||||
/debug/3.2.7:
|
||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
dev: true
|
||||
@ -3049,14 +3069,33 @@ packages:
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
resolve: 1.22.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-module-utils/2.7.3:
|
||||
/eslint-module-utils/2.7.3_ulu2225r2ychl26a37c6o2rfje:
|
||||
resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': '*'
|
||||
eslint-import-resolver-node: '*'
|
||||
eslint-import-resolver-typescript: '*'
|
||||
eslint-import-resolver-webpack: '*'
|
||||
peerDependenciesMeta:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
eslint-import-resolver-node:
|
||||
optional: true
|
||||
eslint-import-resolver-typescript:
|
||||
optional: true
|
||||
eslint-import-resolver-webpack:
|
||||
optional: true
|
||||
dependencies:
|
||||
debug: 3.2.7
|
||||
eslint-import-resolver-node: 0.3.6
|
||||
find-up: 2.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-eslint-comments/3.2.0_eslint@8.14.0:
|
||||
@ -3074,7 +3113,11 @@ packages:
|
||||
resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==}
|
||||
engines: {node: '>=4'}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': '*'
|
||||
eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
|
||||
peerDependenciesMeta:
|
||||
'@typescript-eslint/parser':
|
||||
optional: true
|
||||
dependencies:
|
||||
array-includes: 3.1.4
|
||||
array.prototype.flat: 1.2.5
|
||||
@ -3082,7 +3125,7 @@ packages:
|
||||
doctrine: 2.1.0
|
||||
eslint: 8.14.0
|
||||
eslint-import-resolver-node: 0.3.6
|
||||
eslint-module-utils: 2.7.3
|
||||
eslint-module-utils: 2.7.3_ulu2225r2ychl26a37c6o2rfje
|
||||
has: 1.0.3
|
||||
is-core-module: 2.8.1
|
||||
is-glob: 4.0.3
|
||||
@ -3090,6 +3133,10 @@ packages:
|
||||
object.values: 1.1.5
|
||||
resolve: 1.22.0
|
||||
tsconfig-paths: 3.14.1
|
||||
transitivePeerDependencies:
|
||||
- eslint-import-resolver-typescript
|
||||
- eslint-import-resolver-webpack
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-unicorn/42.0.0_eslint@8.14.0:
|
||||
@ -3429,6 +3476,8 @@ packages:
|
||||
parseurl: 1.3.3
|
||||
statuses: 1.5.0
|
||||
unpipe: 1.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/find-up/2.1.0:
|
||||
@ -5141,9 +5190,8 @@ packages:
|
||||
dev: true
|
||||
|
||||
/to-fast-properties/2.0.0:
|
||||
resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=}
|
||||
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/to-regex-range/5.0.1:
|
||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||
@ -5580,6 +5628,7 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- rollup
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/vite/2.9.6_sass@1.51.0:
|
||||
|
@ -3,6 +3,7 @@ import { Menu, MenuButton, MenuItems } from "@headlessui/vue";
|
||||
import IconMdiMenuDown from "~icons/mdi/menu-down";
|
||||
import IconMdiMenuUp from "~icons/mdi/menu-up";
|
||||
import Button from "~/components/design/Button.vue";
|
||||
import ServerOnly from "~/components/design/Tooltip.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@ -23,7 +24,7 @@ const props = withDefaults(
|
||||
<template>
|
||||
<Menu v-slot="{ open }">
|
||||
<div>
|
||||
<MenuButton>
|
||||
<MenuButton as="div">
|
||||
<Button :button-type="props.buttonType" :size="props.buttonSize">
|
||||
<slot name="button-label">
|
||||
<span class="mx-1">{{ props.name }}</span>
|
||||
|
@ -21,11 +21,10 @@ const hasError = computed<boolean>(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientOnly>
|
||||
<Popper v-bind="$attrs" :show="hasError" arrow placement="bottom" :content="formattedError" class="text-center">
|
||||
<slot />
|
||||
</Popper>
|
||||
</ClientOnly>
|
||||
<div><slot /></div>
|
||||
<!--<Popper v-bind="$attrs" :show="hasError" arrow placement="bottom" :content="formattedError" class="text-center">
|
||||
<slot />
|
||||
</Popper>-->
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -95,8 +95,8 @@ export interface Step {
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<Card accent>
|
||||
<template v-if="settings.mobile" #header>
|
||||
{{ activeStep.header }}
|
||||
<template #header>
|
||||
<span v-show="settings.mobile">{{ activeStep.header }}</span>
|
||||
</template>
|
||||
<div v-for="step in steps" :key="step.value">
|
||||
<slot v-if="internalValue === step.value" :name="step.value" />
|
||||
|
@ -132,7 +132,7 @@ interface EditableMember {
|
||||
<p class="font-semibold">
|
||||
<Link :to="'/' + member.user.name">{{ member.user.name }}</Link>
|
||||
</p>
|
||||
<Tooltip :disabled="member.role.accepted">
|
||||
<Tooltip v-if="member.role.accepted">
|
||||
<template #content>
|
||||
{{ i18n.t("form.memberList.invitedAs", [member.role.role.title]) }}
|
||||
</template>
|
||||
|
@ -68,7 +68,7 @@ function toggleWatch() {
|
||||
:img-src="imageUrl"
|
||||
/>
|
||||
<div class="flex-grow sm:mr-4 <sm:mb-4 overflow-clip">
|
||||
<p class="text-2xl <sm:text-lg pb-1 inline-flex space-x-1.2 items-center">
|
||||
<div class="text-2xl <sm:text-lg pb-1 inline-flex space-x-1.2 items-center">
|
||||
<UserAvatar
|
||||
class="!w-8 !h-8 sm:hidden"
|
||||
:username="project.namespace.owner"
|
||||
@ -78,7 +78,7 @@ function toggleWatch() {
|
||||
<router-link class="!sm:ml-0" :to="'/' + project.namespace.owner">{{ project.namespace.owner }}</router-link>
|
||||
<span class="text-gray-500 dark:text-gray-400"> / </span>
|
||||
<span class="font-semibold">{{ project.name }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<p>{{ project.description }}</p>
|
||||
</div>
|
||||
<div class="flex sm:flex-col space-y-2 items-end justify-between sm:justify-around flex-shrink-0">
|
||||
|
@ -12,6 +12,8 @@ import devalue from "@nuxt/devalue";
|
||||
import { settingsLog } from "~/composables/useLog";
|
||||
import * as domain from "~/composables/useDomain";
|
||||
|
||||
import "regenerator-runtime/runtime"; // popper needs this?
|
||||
|
||||
const routes = setupLayouts(generatedRoutes);
|
||||
// we need to override the path on the error route to have the patch math
|
||||
const errorRoute = routes.find((r) => r.path === "/error");
|
||||
|
@ -216,9 +216,9 @@ useHead(
|
||||
<InputTag
|
||||
v-model="form.settings.keywords"
|
||||
counter
|
||||
:maxlength="backendData.validations.project.keywords.max"
|
||||
:maxlength="backendData.validations?.project.keywords.max"
|
||||
:label="i18n.t('project.new.step3.keywords')"
|
||||
:rules="[required(), maxLength()(backendData.validations.project.keywords.max)]"
|
||||
:rules="[required(), maxLength()(backendData.validations?.project.keywords.max)]"
|
||||
/>
|
||||
</ProjectSettingsSection>
|
||||
<ProjectSettingsSection>
|
||||
|
@ -9,7 +9,7 @@ import { useBackendDataStore } from "~/store/backendData";
|
||||
import { lastUpdated } from "~/composables/useTime";
|
||||
import { useInternalApi } from "~/composables/useApi";
|
||||
import { handleRequestError } from "~/composables/useErrorHandling";
|
||||
import { Tag } from "hangar-api";
|
||||
import { Tag, User } from "hangar-api";
|
||||
import { useErrorRedirect } from "~/composables/useErrorRedirect";
|
||||
import TagComponent from "~/components/Tag.vue";
|
||||
import { hasPerms } from "~/composables/usePerm";
|
||||
@ -25,7 +25,6 @@ import { useNotificationStore } from "~/store/notification";
|
||||
import DropdownButton from "~/components/design/DropdownButton.vue";
|
||||
import DropdownItem from "~/components/design/DropdownItem.vue";
|
||||
import PlatformVersionEditModal from "~/components/modals/PlatformVersionEditModal.vue";
|
||||
import Tooltip from "~/components/design/Tooltip.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const i18n = useI18n();
|
||||
@ -38,6 +37,9 @@ const props = defineProps<{
|
||||
versions: Map<Platform, HangarVersion>;
|
||||
project: HangarProject;
|
||||
versionPlatforms: Set<Platform>;
|
||||
user: User;
|
||||
platform: string;
|
||||
version: string;
|
||||
}>();
|
||||
|
||||
const p: Platform = ((route.params.platform as string) || "").toUpperCase() as Platform;
|
||||
|
@ -136,7 +136,7 @@ function getNonChannelTags(version: Version): ApiTag[] {
|
||||
<div class="flex flex-wrap">
|
||||
<span class="basis-full inline-flex items-center">
|
||||
<IconMdiAccountArrowRight class="mr-1" />
|
||||
<Link :to="'/' + version.author">{{ version.author }}</Link>
|
||||
{{ version.author }}
|
||||
</span>
|
||||
<span class="basis-full inline-flex items-center">
|
||||
<IconMdiFile class="mr-1" />
|
||||
|
@ -103,7 +103,7 @@ useHead(useSeo(props.user.name, props.user.tagline, route, avatarUrl(props.user.
|
||||
<ul>
|
||||
<li v-for="(orgRole, orgName) in organizations" :key="orgName">
|
||||
<router-link :to="'/' + orgName" class="flex">
|
||||
<UserAvatar :username="orgName" :avatar-url="avatarUrl(orgName)" size="xs" />
|
||||
<UserAvatar :username="orgName" :avatar-url="avatarUrl(orgName)" size="xs" :disable-link="true" />
|
||||
|
||||
{{ orgName }}
|
||||
({{ orgRole.role.title }})
|
||||
|
@ -48,48 +48,44 @@ export const useBackendDataStore = defineStore("backendData", () => {
|
||||
|
||||
async function initBackendData() {
|
||||
try {
|
||||
// todo make these run concurrently to speed up stuff, also consider caching them in node server/globally, these are all always needed
|
||||
await fetchIfNeeded(async () => {
|
||||
const categoryResult = await useInternalApi<IProjectCategory[]>("data/categories", false);
|
||||
for (const c of categoryResult) {
|
||||
c.title = "project.category." + c.apiName;
|
||||
}
|
||||
return convertToMap<ProjectCategory, IProjectCategory>(categoryResult, (value) => value.apiName);
|
||||
}, projectCategories);
|
||||
// todo consider caching these in node server/globally, these are all always needed
|
||||
await Promise.all([
|
||||
fetchIfNeeded(async () => {
|
||||
const categoryResult = await useInternalApi<IProjectCategory[]>("data/categories", false);
|
||||
for (const c of categoryResult) {
|
||||
c.title = "project.category." + c.apiName;
|
||||
}
|
||||
return convertToMap<ProjectCategory, IProjectCategory>(categoryResult, (value) => value.apiName);
|
||||
}, projectCategories),
|
||||
|
||||
await fetchIfNeeded(async () => {
|
||||
const permissionResultTemp = await useInternalApi<{ value: NamedPermission; frontendName: string; permission: string }[]>("data/permissions", false);
|
||||
const permissionResult: IPermission[] = permissionResultTemp.map(({ value, frontendName, permission }) => ({
|
||||
value,
|
||||
frontendName,
|
||||
permission: BigInt("0b" + permission),
|
||||
}));
|
||||
return convertToMap<NamedPermission, IPermission>(permissionResult, (value) => value.value);
|
||||
}, permissions);
|
||||
fetchIfNeeded(async () => {
|
||||
const permissionResultTemp = await useInternalApi<{ value: NamedPermission; frontendName: string; permission: string }[]>("data/permissions", false);
|
||||
const permissionResult: IPermission[] = permissionResultTemp.map(({ value, frontendName, permission }) => ({
|
||||
value,
|
||||
frontendName,
|
||||
permission: BigInt("0b" + permission),
|
||||
}));
|
||||
return convertToMap<NamedPermission, IPermission>(permissionResult, (value) => value.value);
|
||||
}, permissions),
|
||||
|
||||
await fetchIfNeeded(async () => {
|
||||
const platformResult: IPlatform[] = await useInternalApi<IPlatform[]>("data/platforms", false);
|
||||
return convertToMap<Platform, IPlatform>(platformResult, (value) => value.name.toUpperCase());
|
||||
}, platforms);
|
||||
fetchIfNeeded(async () => {
|
||||
const platformResult: IPlatform[] = await useInternalApi<IPlatform[]>("data/platforms", false);
|
||||
return convertToMap<Platform, IPlatform>(platformResult, (value) => value.name.toUpperCase());
|
||||
}, platforms),
|
||||
|
||||
await fetchIfNeeded(async () => {
|
||||
const promptsResult: IPrompt[] = await useInternalApi<IPrompt[]>("data/prompts", false);
|
||||
return convertToMap<Prompt, IPrompt>(promptsResult, (value) => value.name);
|
||||
}, prompts);
|
||||
fetchIfNeeded(async () => {
|
||||
const promptsResult: IPrompt[] = await useInternalApi<IPrompt[]>("data/prompts", false);
|
||||
return convertToMap<Prompt, IPrompt>(promptsResult, (value) => value.name);
|
||||
}, prompts),
|
||||
|
||||
await fetchIfNeeded(async () => useInternalApi<string[]>("data/licenses", false), licenses);
|
||||
|
||||
await fetchIfNeeded(async () => useInternalApi<AnnouncementObject[]>("data/announcements", false), announcements);
|
||||
|
||||
await fetchIfNeeded(async () => useInternalApi<IVisibility[]>("data/visibilities", false), visibilities);
|
||||
|
||||
await fetchIfNeeded(async () => useInternalApi("data/validations", false), validations);
|
||||
|
||||
await fetchIfNeeded(async () => useInternalApi("data/orgRoles", false), orgRoles);
|
||||
|
||||
await fetchIfNeeded(async () => useInternalApi("data/channelColors", false), channelColors);
|
||||
|
||||
await fetchIfNeeded(async () => useInternalApi("data/projectRoles", false), projectRoles);
|
||||
fetchIfNeeded(async () => useInternalApi<string[]>("data/licenses", false), licenses),
|
||||
fetchIfNeeded(async () => useInternalApi<AnnouncementObject[]>("data/announcements", false), announcements),
|
||||
fetchIfNeeded(async () => useInternalApi<IVisibility[]>("data/visibilities", false), visibilities),
|
||||
fetchIfNeeded(async () => useInternalApi("data/validations", false), validations),
|
||||
fetchIfNeeded(async () => useInternalApi("data/orgRoles", false), orgRoles),
|
||||
fetchIfNeeded(async () => useInternalApi("data/channelColors", false), channelColors),
|
||||
fetchIfNeeded(async () => useInternalApi("data/projectRoles", false), projectRoles),
|
||||
]);
|
||||
} catch (e) {
|
||||
console.error("ERROR FETCHING BACKEND DATA");
|
||||
console.error(e);
|
||||
|
Loading…
Reference in New Issue
Block a user