mirror of
https://github.com/HangarMC/Hangar.git
synced 2024-11-27 06:01:08 +08:00
Add platform versions to download dropdown
This commit is contained in:
parent
0cc6d06c4c
commit
f9c4d652df
@ -1,7 +1,2 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
cd frontend
|
||||
pnpm prettier --write src/types/generated/**.*
|
||||
pnpm lint-staged
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import Button from "~/lib/components/design/Button.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { HangarProject, HangarVersion, PinnedVersion } from "hangar-internal";
|
||||
import { computed, ref } from "vue";
|
||||
import { HangarProject, PinnedVersion } from "hangar-internal";
|
||||
import { computed } from "vue";
|
||||
import { Platform } from "~/types/enums";
|
||||
import DropdownButton from "~/lib/components/design/DropdownButton.vue";
|
||||
import { formatVersionNumbers } from "~/composables/useVersionHelper";
|
||||
import { useBackendDataStore } from "~/store/backendData";
|
||||
import DropdownItem from "~/lib/components/design/DropdownItem.vue";
|
||||
import PlatformLogo from "~/components/logos/PlatformLogo.vue";
|
||||
@ -54,7 +55,7 @@ const external = computed(() => false);
|
||||
</span>
|
||||
</template>
|
||||
<DropdownItem
|
||||
v-for="platform in pinnedVersion.platforms"
|
||||
v-for="(v, platform) in pinnedVersion.platformDependencies"
|
||||
:key="platform"
|
||||
class="flex items-center"
|
||||
:href="downloadLink(platform, pinnedVersion)"
|
||||
@ -63,6 +64,7 @@ const external = computed(() => false);
|
||||
>
|
||||
<PlatformLogo :platform="platform" :size="24" class="mr-1" />
|
||||
{{ backendData.platforms?.get(platform).name }}
|
||||
<span class="ml-1">({{ formatVersionNumbers(v) }})</span>
|
||||
</DropdownItem>
|
||||
</DropdownButton>
|
||||
|
||||
@ -90,6 +92,7 @@ const external = computed(() => false);
|
||||
>
|
||||
<PlatformLogo :platform="p" :size="24" class="mr-1" />
|
||||
{{ backendData.platforms?.get(p).name }}
|
||||
<span v-if="v.platformDependencies" class="ml-1">({{ formatVersionNumbers(v.platformDependencies[p]) }})</span>
|
||||
</DropdownItem>
|
||||
</DropdownButton>
|
||||
</div>
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 7480c33fa1aac6127a2f55ac9cac4d3b9e5327f5
|
||||
Subproject commit c9e053c9e6af57301b514520876bd72ad3e97632
|
@ -105,7 +105,7 @@ useHead(useSeo(props.project.name, props.project.description, route, projectIcon
|
||||
<br />
|
||||
<div class="inline-flex items-center">
|
||||
<Tag :name="version.channel.name" :color="{ background: version.channel.color }" />
|
||||
<PlatformLogo v-for="(platform, idx) in version.platforms" :key="`${idx}-${platform}`" :platform="platform" :size="24" class="ml-1" />
|
||||
<PlatformLogo v-for="(v, p) in version.platformDependencies" :key="p" :platform="p" :size="24" class="ml-1" />
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
|
@ -54,7 +54,7 @@ useHead(useSeo(i18n.t("userActionLog.title"), null, route, null));
|
||||
</template>
|
||||
<template v-else-if="item.version">
|
||||
<Link :to="'/' + item.project.owner + '/' + item.project.slug + '/versions/' + item.version.versionString">
|
||||
{{ `${item.project.owner}/${item.project.slug}/${item.version.versionString}/${item.version.platforms[0].toLowerCase()}` }}
|
||||
{{ `${item.project.owner}/${item.project.slug}/${item.version.versionString}` }}
|
||||
</Link>
|
||||
</template>
|
||||
<template v-else-if="item.project && item.project.owner">
|
||||
|
11
frontend/src/types/generated/icons.d.ts
vendored
11
frontend/src/types/generated/icons.d.ts
vendored
@ -14,34 +14,23 @@ declare module '@vue/runtime-core' {
|
||||
IconMdiCalendar: typeof import('~icons/mdi/calendar')['default']
|
||||
IconMdiCheck: typeof import('~icons/mdi/check')['default']
|
||||
IconMdiCheckBold: typeof import('~icons/mdi/check-bold')['default']
|
||||
IconMdiCheckboxMarkedCircle: typeof import('~icons/mdi/checkbox-marked-circle')['default']
|
||||
IconMdiCheckCircleOutline: typeof import('~icons/mdi/check-circle-outline')['default']
|
||||
IconMdiCircle: typeof import('~icons/mdi/circle')['default']
|
||||
IconMdiClipboardOutline: typeof import('~icons/mdi/clipboard-outline')['default']
|
||||
IconMdiClose: typeof import('~icons/mdi/close')['default']
|
||||
IconMdiCloseCircle: typeof import('~icons/mdi/close-circle')['default']
|
||||
IconMdiContentCopy: typeof import('~icons/mdi/content-copy')['default']
|
||||
IconMdiContentSave: typeof import('~icons/mdi/content-save')['default']
|
||||
IconMdiDelete: typeof import('~icons/mdi/delete')['default']
|
||||
IconMdiDiamond: typeof import('~icons/mdi/diamond')['default']
|
||||
IconMdiDiamondStone: typeof import('~icons/mdi/diamond-stone')['default']
|
||||
IconMdiDownload: typeof import('~icons/mdi/download')['default']
|
||||
IconMdiDownloadOutline: typeof import('~icons/mdi/download-outline')['default']
|
||||
IconMdiEye: typeof import('~icons/mdi/eye')['default']
|
||||
IconMdiEyeOff: typeof import('~icons/mdi/eye-off')['default']
|
||||
IconMdiFile: typeof import('~icons/mdi/file')['default']
|
||||
IconMdiFlag: typeof import('~icons/mdi/flag')['default']
|
||||
IconMdiHome: typeof import('~icons/mdi/home')['default']
|
||||
IconMdiInformation: typeof import('~icons/mdi/information')['default']
|
||||
IconMdiKeyOutline: typeof import('~icons/mdi/key-outline')['default']
|
||||
IconMdiListStatus: typeof import('~icons/mdi/list-status')['default']
|
||||
IconMdiMenu: typeof import('~icons/mdi/menu')['default']
|
||||
IconMdiMenuDown: typeof import('~icons/mdi/menu-down')['default']
|
||||
IconMdiOpenInNew: typeof import('~icons/mdi/open-in-new')['default']
|
||||
IconMdiPencil: typeof import('~icons/mdi/pencil')['default']
|
||||
IconMdiPin: typeof import('~icons/mdi/pin')['default']
|
||||
IconMdiPinOff: typeof import('~icons/mdi/pin-off')['default']
|
||||
IconMdiPlay: typeof import('~icons/mdi/play')['default']
|
||||
IconMdiPlus: typeof import('~icons/mdi/plus')['default']
|
||||
IconMdiSortVariant: typeof import('~icons/mdi/sort-variant')['default']
|
||||
IconMdiStar: typeof import('~icons/mdi/star')['default']
|
||||
|
10
frontend/src/types/internal/projects.d.ts
vendored
10
frontend/src/types/internal/projects.d.ts
vendored
@ -1,8 +1,8 @@
|
||||
declare module "hangar-internal" {
|
||||
import type { Joinable, Table } from "hangar-internal";
|
||||
import type { Project, ProjectNamespace } from "hangar-api";
|
||||
import type { ProjectCategory, Visibility } from "~/types/enums";
|
||||
import { Platform } from "~/types/enums";
|
||||
import type {Joinable, Table} from "hangar-internal";
|
||||
import type {Project, ProjectNamespace} from "hangar-api";
|
||||
import type {ProjectCategory, Visibility} from "~/types/enums";
|
||||
import {Platform} from "~/types/enums";
|
||||
|
||||
interface ProjectOwner {
|
||||
id: number;
|
||||
@ -30,7 +30,7 @@ declare module "hangar-internal" {
|
||||
interface PinnedVersion {
|
||||
type: 'channel' | 'version';
|
||||
name: string;
|
||||
platforms: Platform[];
|
||||
platformDependencies: Record<Platform, string[]>;
|
||||
channel: ProjectChannel;
|
||||
fileInfo: FileInfo | null;
|
||||
externalUrl: string | null;
|
||||
|
@ -103,9 +103,9 @@ public interface HangarVersionsDAO {
|
||||
List<HangarVersion> getVersionsWithVersionString(String author, String slug, String versionString, @Define boolean canSeeHidden, @Define Long userId);
|
||||
|
||||
@SqlQuery("""
|
||||
SELECT pv."type",
|
||||
SELECT pv.version_id,
|
||||
pv."type",
|
||||
pv.version_string AS name,
|
||||
pv.platforms,
|
||||
pc.name pc_name,
|
||||
pc.created_at pc_created_at,
|
||||
pc.color pc_color,
|
||||
|
@ -14,15 +14,17 @@ import io.papermc.hangar.model.identified.ProjectIdentified;
|
||||
import io.papermc.hangar.model.internal.Joinable;
|
||||
import io.papermc.hangar.model.internal.user.JoinableMember;
|
||||
import io.papermc.hangar.model.internal.versions.HangarVersion;
|
||||
import org.jdbi.v3.core.enums.EnumByName;
|
||||
import org.jdbi.v3.core.mapper.Nested;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jdbi.v3.core.enums.EnumByName;
|
||||
import org.jdbi.v3.core.mapper.Nested;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class HangarProject extends Project implements Joinable<ProjectRoleTable>, ProjectIdentified {
|
||||
|
||||
private final long id;
|
||||
@ -118,7 +120,7 @@ public class HangarProject extends Project implements Joinable<ProjectRoleTable>
|
||||
private final long starCount;
|
||||
private final long watcherCount;
|
||||
|
||||
public HangarProjectInfo(int publicVersions, int flagCount, int noteCount, long starCount, long watcherCount) {
|
||||
public HangarProjectInfo(final int publicVersions, final int flagCount, final int noteCount, final long starCount, final long watcherCount) {
|
||||
this.publicVersions = publicVersions;
|
||||
this.flagCount = flagCount;
|
||||
this.noteCount = noteCount;
|
||||
@ -161,8 +163,66 @@ public class HangarProject extends Project implements Joinable<ProjectRoleTable>
|
||||
}
|
||||
|
||||
|
||||
public record PinnedVersion(Type type, String name, Set<Platform> platforms, @Nested("pc") ProjectChannel channel,
|
||||
@Nested("fi") @Nullable FileInfo fileInfo, @Nullable String externalUrl) {
|
||||
public static class PinnedVersion {
|
||||
private final long versionId;
|
||||
private final Type type;
|
||||
private final String name;
|
||||
private final ProjectChannel channel;
|
||||
private final FileInfo fileInfo;
|
||||
private final String externalUrl;
|
||||
private final Map<Platform, Set<String>> platformDependencies;
|
||||
|
||||
public PinnedVersion(long versionId, Type type, String name, @Nested("pc") ProjectChannel channel,
|
||||
@Nested("fi") @Nullable FileInfo fileInfo, @Nullable String externalUrl) {
|
||||
this.versionId = versionId;
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.channel = channel;
|
||||
this.fileInfo = fileInfo;
|
||||
this.externalUrl = externalUrl;
|
||||
this.platformDependencies = new EnumMap<>(Platform.class);
|
||||
}
|
||||
|
||||
public long getVersionId() {
|
||||
return versionId;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Map<Platform, Set<String>> getPlatformDependencies() {
|
||||
return platformDependencies;
|
||||
}
|
||||
|
||||
public ProjectChannel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public FileInfo getFileInfo() {
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
public String getExternalUrl() {
|
||||
return externalUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PinnedVersion[" +
|
||||
"versionId=" + versionId + ", " +
|
||||
"type=" + type + ", " +
|
||||
"name=" + name + ", " +
|
||||
"platforms=" + platformDependencies + ", " +
|
||||
"channel=" + channel + ", " +
|
||||
"fileInfo=" + fileInfo + ", " +
|
||||
"externalUrl=" + externalUrl + ']';
|
||||
}
|
||||
|
||||
|
||||
@EnumByName
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
|
@ -10,6 +10,7 @@ import io.papermc.hangar.db.dao.internal.versions.HangarVersionsDAO;
|
||||
import io.papermc.hangar.db.dao.v1.VersionsApiDAO;
|
||||
import io.papermc.hangar.exceptions.HangarApiException;
|
||||
import io.papermc.hangar.model.api.project.Project;
|
||||
import io.papermc.hangar.model.api.project.version.PluginDependency;
|
||||
import io.papermc.hangar.model.api.requests.RequestPagination;
|
||||
import io.papermc.hangar.model.common.Permission;
|
||||
import io.papermc.hangar.model.common.Platform;
|
||||
@ -42,6 +43,7 @@ import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -128,8 +130,12 @@ public class ProjectService extends HangarComponent {
|
||||
|
||||
final Map<Platform, HangarVersion> mainChannelVersions = new EnumMap<>(Platform.class);
|
||||
for (final Platform platform : Platform.getValues()) {
|
||||
final HangarVersion version = getLastVersion(author, slug, platform, config.channels.getNameDefault());
|
||||
final HangarVersion version = getLastVersion(author, slug, platform, config.channels.getNameDefault());
|
||||
if (version != null) {
|
||||
if (version.getPlatformDependencies().isEmpty()) {
|
||||
version.getPlatformDependencies().putAll(versionsApiDAO.getPlatformDependencies(version.getId()));
|
||||
}
|
||||
|
||||
mainChannelVersions.put(platform, version);
|
||||
}
|
||||
}
|
||||
|
@ -3,23 +3,27 @@ package io.papermc.hangar.service.internal.versions;
|
||||
import io.papermc.hangar.HangarComponent;
|
||||
import io.papermc.hangar.db.dao.internal.table.versions.PinnedProjectVersionsDAO;
|
||||
import io.papermc.hangar.db.dao.internal.versions.HangarVersionsDAO;
|
||||
import io.papermc.hangar.db.dao.v1.VersionsApiDAO;
|
||||
import io.papermc.hangar.model.db.versions.PinnedProjectVersionTable;
|
||||
import io.papermc.hangar.model.internal.projects.HangarProject;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@Transactional
|
||||
public class PinnedVersionService extends HangarComponent {
|
||||
|
||||
private final HangarVersionsDAO hangarVersionsDAO;
|
||||
private final VersionsApiDAO versionsApiDAO;
|
||||
private final PinnedProjectVersionsDAO pinnedProjectVersionsDAO;
|
||||
|
||||
@Autowired
|
||||
public PinnedVersionService(final HangarVersionsDAO hangarVersionsDAO, final PinnedProjectVersionsDAO pinnedProjectVersionsDAO) {
|
||||
public PinnedVersionService(final HangarVersionsDAO hangarVersionsDAO, final VersionsApiDAO versionsApiDAO, final PinnedProjectVersionsDAO pinnedProjectVersionsDAO) {
|
||||
this.hangarVersionsDAO = hangarVersionsDAO;
|
||||
this.versionsApiDAO = versionsApiDAO;
|
||||
this.pinnedProjectVersionsDAO = pinnedProjectVersionsDAO;
|
||||
}
|
||||
|
||||
@ -33,6 +37,10 @@ public class PinnedVersionService extends HangarComponent {
|
||||
}
|
||||
|
||||
public List<HangarProject.PinnedVersion> getPinnedVersions(final long projectId) {
|
||||
return this.hangarVersionsDAO.getPinnedVersions(projectId);
|
||||
final List<HangarProject.PinnedVersion> versions = this.hangarVersionsDAO.getPinnedVersions(projectId);
|
||||
for (final HangarProject.PinnedVersion version : versions) {
|
||||
version.getPlatformDependencies().putAll(versionsApiDAO.getPlatformDependencies(version.getVersionId()));
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user