You've already forked AstralRinth
forked from didirus/AstralRinth
Datapack support (#815)
* Shader support PR * Make search page work * Fix env showing * Make moderation look reasonable * Fix search for shaders * Datapack support * Make file types work + datapack inferring * Add editing to file types * Finish datapack file generation * Fix bugs, make forge support work * Fix inconsistent data pack label * Final fixes
This commit is contained in:
@@ -45,7 +45,9 @@
|
||||
<div
|
||||
v-if="
|
||||
project.project_type !== 'resourcepack' &&
|
||||
project.project_type !== 'plugin'
|
||||
project.project_type !== 'plugin' &&
|
||||
project.project_type !== 'shader' &&
|
||||
project.project_type !== 'datapack'
|
||||
"
|
||||
>
|
||||
<div
|
||||
@@ -502,7 +504,8 @@
|
||||
v-if="
|
||||
project.project_type !== 'resourcepack' &&
|
||||
project.project_type !== 'plugin' &&
|
||||
project.project_type !== 'shader'
|
||||
project.project_type !== 'shader' &&
|
||||
project.project_type !== 'datapack'
|
||||
"
|
||||
class="info"
|
||||
>
|
||||
@@ -515,7 +518,8 @@
|
||||
v-if="
|
||||
project.project_type !== 'resourcepack' &&
|
||||
project.project_type !== 'plugin' &&
|
||||
project.project_type !== 'shader'
|
||||
project.project_type !== 'shader' &&
|
||||
project.project_type !== 'datapack'
|
||||
"
|
||||
class="info"
|
||||
>
|
||||
@@ -843,10 +847,9 @@ export default {
|
||||
this.featuredVersions = this.$computeVersions(this.featuredVersions)
|
||||
},
|
||||
head() {
|
||||
const title = `${this.project.title} - Minecraft ${
|
||||
this.projectTypeDisplay.charAt(0).toUpperCase() +
|
||||
this.projectTypeDisplay.slice(1)
|
||||
}`
|
||||
const title = `${this.project.title} - Minecraft ${this.$formatProjectType(
|
||||
this.projectTypeDisplay
|
||||
)}`
|
||||
|
||||
return {
|
||||
title,
|
||||
@@ -869,9 +872,11 @@ export default {
|
||||
{
|
||||
hid: 'description',
|
||||
name: 'description',
|
||||
content: `${this.project.description} - Download the Minecraft ${
|
||||
content: `${
|
||||
this.project.description
|
||||
} - Download the Minecraft ${this.$formatProjectType(
|
||||
this.projectTypeDisplay
|
||||
} ${this.project.title} by ${
|
||||
)} ${this.project.title} by ${
|
||||
this.members.find((x) => x.role === 'Owner').user.username
|
||||
} on Modrinth`,
|
||||
},
|
||||
|
||||
@@ -209,7 +209,8 @@
|
||||
<section
|
||||
v-if="
|
||||
project.project_type !== 'resourcepack' &&
|
||||
project.project_type !== 'shader'
|
||||
project.project_type !== 'shader' &&
|
||||
project.project_type !== 'datapack'
|
||||
"
|
||||
class="card game-sides"
|
||||
>
|
||||
@@ -833,6 +834,9 @@ export default {
|
||||
this.newProject.client_side = this.clientSideType.toLowerCase()
|
||||
this.newProject.server_side = this.serverSideType.toLowerCase()
|
||||
|
||||
this.newProject.client_side = this.clientSideType.toLowerCase()
|
||||
this.newProject.server_side = this.serverSideType.toLowerCase()
|
||||
|
||||
this.$emit('update:project', this.newProject)
|
||||
|
||||
this.isEditing = false
|
||||
|
||||
@@ -371,7 +371,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', this._keyListener.bind(this))
|
||||
// eslint-disable-next-line nuxt/no-env-in-hooks
|
||||
if (process.client) {
|
||||
document.addEventListener('keydown', this._keyListener.bind(this))
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showPreviewImage(files, index) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div v-if="version" class="version-page">
|
||||
<ModalConfirm
|
||||
v-if="$auth.user && currentMember"
|
||||
ref="modal_confirm"
|
||||
title="Are you sure you want to delete this version?"
|
||||
description="This will remove this version forever (like really forever)."
|
||||
@@ -14,6 +15,58 @@
|
||||
:item-id="version.id"
|
||||
item-type="version"
|
||||
/>
|
||||
<Modal
|
||||
v-if="$auth.user && currentMember"
|
||||
ref="modal_package_mod"
|
||||
header="Package data pack"
|
||||
>
|
||||
<div class="modal-package-mod universal-labels">
|
||||
<div class="markdown-body">
|
||||
<p>
|
||||
Package your data pack as a mod. This will create a new version with
|
||||
support for the selected mod loaders. You will be redirected to the
|
||||
new version and can edit it to your liking.
|
||||
</p>
|
||||
</div>
|
||||
<label for="package-mod-loaders">
|
||||
<span class="label__title">Mod loaders</span>
|
||||
<span class="label__description">
|
||||
The mod loaders you would like to package your data pack for.
|
||||
</span>
|
||||
</label>
|
||||
<multiselect
|
||||
id="package-mod-loaders"
|
||||
v-model="packageLoaders"
|
||||
:options="['fabric', 'forge', 'quilt']"
|
||||
:custom-label="
|
||||
(value) => value.charAt(0).toUpperCase() + value.slice(1)
|
||||
"
|
||||
:multiple="true"
|
||||
:searchable="false"
|
||||
:show-no-results="false"
|
||||
:show-labels="false"
|
||||
placeholder="Choose loaders.."
|
||||
open-direction="top"
|
||||
/>
|
||||
<div class="button-group">
|
||||
<button
|
||||
class="iconified-button"
|
||||
@click="$refs.modal_package_mod.hide()"
|
||||
>
|
||||
<CrossIcon />
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
class="iconified-button brand-button"
|
||||
:disabled="!$nuxt.$loading"
|
||||
@click="createDataPackVersion"
|
||||
>
|
||||
<RightArrowIcon />
|
||||
Begin packaging data pack
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<div class="version-page__title universal-card">
|
||||
<div class="version-header">
|
||||
<template v-if="isEditing">
|
||||
@@ -143,7 +196,7 @@
|
||||
Back to list
|
||||
</nuxt-link>
|
||||
<button
|
||||
v-if="$auth.user"
|
||||
v-if="$auth.user && !currentMember"
|
||||
class="iconified-button"
|
||||
@click="$refs.modal_version_report.show()"
|
||||
>
|
||||
@@ -164,6 +217,19 @@
|
||||
<EditIcon aria-hidden="true" />
|
||||
Edit
|
||||
</nuxt-link>
|
||||
<button
|
||||
v-if="
|
||||
currentMember &&
|
||||
version.loaders.some((x) =>
|
||||
$tag.loaderData.dataPackLoaders.includes(x)
|
||||
)
|
||||
"
|
||||
class="iconified-button"
|
||||
@click="$refs.modal_package_mod.show()"
|
||||
>
|
||||
<BoxIcon aria-hidden="true" />
|
||||
Package as mod
|
||||
</button>
|
||||
<button
|
||||
v-if="currentMember"
|
||||
class="iconified-button danger-button"
|
||||
@@ -222,7 +288,10 @@
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
v-if="version.dependencies.length > 0 || isEditing"
|
||||
v-if="
|
||||
version.dependencies.length > 0 ||
|
||||
(isEditing && project.project_type !== 'modpack')
|
||||
"
|
||||
class="version-page__dependencies universal-card"
|
||||
>
|
||||
<h3>Dependencies</h3>
|
||||
@@ -269,7 +338,7 @@
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
v-if="isEditing"
|
||||
v-if="isEditing && project.project_type !== 'modpack'"
|
||||
class="iconified-button"
|
||||
@click="version.dependencies.splice(index, 1)"
|
||||
>
|
||||
@@ -308,7 +377,7 @@
|
||||
:searchable="false"
|
||||
:close-on-select="true"
|
||||
:show-labels="false"
|
||||
:allow-empty="false"
|
||||
:allow-empty="true"
|
||||
/>
|
||||
<input
|
||||
v-model="newDependencyId"
|
||||
@@ -334,7 +403,7 @@
|
||||
:searchable="false"
|
||||
:close-on-select="true"
|
||||
:show-labels="false"
|
||||
:allow-empty="false"
|
||||
:allow-empty="true"
|
||||
/>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
@@ -385,7 +454,48 @@
|
||||
<span class="filename">
|
||||
<strong>{{ file.filename }}</strong>
|
||||
<span class="file-size">({{ $formatBytes(file.size) }})</span>
|
||||
<span
|
||||
v-if="primaryFile.hashes.sha1 === file.hashes.sha1"
|
||||
class="file-type"
|
||||
>
|
||||
Primary
|
||||
</span>
|
||||
<span
|
||||
v-else-if="
|
||||
file.file_type === 'required-resource-pack' && !isEditing
|
||||
"
|
||||
class="file-type"
|
||||
>
|
||||
Required resource pack
|
||||
</span>
|
||||
<span
|
||||
v-else-if="
|
||||
file.file_type === 'optional-resource-pack' && !isEditing
|
||||
"
|
||||
class="file-type"
|
||||
>
|
||||
Optional resource pack
|
||||
</span>
|
||||
</span>
|
||||
<multiselect
|
||||
v-if="
|
||||
version.loaders.some((x) =>
|
||||
$tag.loaderData.dataPackLoaders.includes(x)
|
||||
) &&
|
||||
isEditing &&
|
||||
primaryFile.hashes.sha1 !== file.hashes.sha1
|
||||
"
|
||||
v-model="oldFileTypes[index]"
|
||||
class="raised-multiselect"
|
||||
placeholder="Select file type"
|
||||
:options="fileTypes"
|
||||
track-by="value"
|
||||
label="display"
|
||||
:searchable="false"
|
||||
:close-on-select="true"
|
||||
:show-labels="false"
|
||||
:allow-empty="false"
|
||||
/>
|
||||
<FileInput
|
||||
v-if="isEditing && primaryFile.hashes.sha1 === file.hashes.sha1"
|
||||
class="iconified-button raised-button"
|
||||
@@ -397,6 +507,8 @@
|
||||
(x) => {
|
||||
deleteFiles.push(file.hashes.sha1)
|
||||
version.files.splice(index, 1)
|
||||
oldFileTypes.splice(index, 1)
|
||||
|
||||
replaceFile = x[0]
|
||||
}
|
||||
"
|
||||
@@ -409,6 +521,7 @@
|
||||
@click="
|
||||
deleteFiles.push(file.hashes.sha1)
|
||||
version.files.splice(index, 1)
|
||||
oldFileTypes.splice(index, 1)
|
||||
"
|
||||
>
|
||||
<TrashIcon />
|
||||
@@ -432,9 +545,29 @@
|
||||
<strong>{{ file.name }}</strong>
|
||||
<span class="file-size">({{ $formatBytes(file.size) }})</span>
|
||||
</span>
|
||||
<multiselect
|
||||
v-if="
|
||||
version.loaders.some((x) =>
|
||||
$tag.loaderData.dataPackLoaders.includes(x)
|
||||
)
|
||||
"
|
||||
v-model="newFileTypes[index]"
|
||||
class="raised-multiselect"
|
||||
placeholder="Select file type"
|
||||
:options="fileTypes"
|
||||
track-by="value"
|
||||
label="display"
|
||||
:searchable="false"
|
||||
:close-on-select="true"
|
||||
:show-labels="false"
|
||||
:allow-empty="false"
|
||||
/>
|
||||
<button
|
||||
class="iconified-button raised-button"
|
||||
@click="newFiles.splice(index, 1)"
|
||||
@click="
|
||||
newFiles.splice(index, 1)
|
||||
newFileTypes.splice(index, 1)
|
||||
"
|
||||
>
|
||||
<TrashIcon />
|
||||
Remove
|
||||
@@ -442,14 +575,29 @@
|
||||
</div>
|
||||
<div class="additional-files">
|
||||
<h4>Upload additional files</h4>
|
||||
<span>Used for files such as sources or Javadocs.</span>
|
||||
<span
|
||||
v-if="
|
||||
version.loaders.some((x) =>
|
||||
$tag.loaderData.dataPackLoaders.includes(x)
|
||||
)
|
||||
"
|
||||
>
|
||||
Used for additional files such as required/optional resource packs
|
||||
</span>
|
||||
<span v-else>Used for files such as sources or Javadocs.</span>
|
||||
<FileInput
|
||||
prompt="Drag and drop to upload or click to select"
|
||||
multiple
|
||||
long-style
|
||||
:accept="acceptFileFromProjectType(project.project_type)"
|
||||
:max-size="524288000"
|
||||
@change="(x) => x.forEach((y) => newFiles.push(y))"
|
||||
@change="
|
||||
(x) =>
|
||||
x.forEach((y) => {
|
||||
newFiles.push(y)
|
||||
newFileTypes.push(null)
|
||||
})
|
||||
"
|
||||
>
|
||||
<UploadIcon />
|
||||
</FileInput>
|
||||
@@ -629,6 +777,7 @@ import Multiselect from 'vue-multiselect'
|
||||
import {
|
||||
acceptFileFromProjectType,
|
||||
inferVersionInfo,
|
||||
createDataPackVersion,
|
||||
} from '~/plugins/fileUtils'
|
||||
|
||||
import VersionBadge from '~/components/ui/Badge'
|
||||
@@ -654,9 +803,13 @@ import PlusIcon from '~/assets/images/utils/plus.svg?inline'
|
||||
import TransferIcon from '~/assets/images/utils/transfer.svg?inline'
|
||||
import UploadIcon from '~/assets/images/utils/upload.svg?inline'
|
||||
import BackIcon from '~/assets/images/utils/left-arrow.svg?inline'
|
||||
import BoxIcon from '~/assets/images/utils/box.svg?inline'
|
||||
import RightArrowIcon from '~/assets/images/utils/right-arrow.svg?inline'
|
||||
import Modal from '~/components/ui/Modal.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Modal,
|
||||
FileInput,
|
||||
Checkbox,
|
||||
Chips,
|
||||
@@ -680,6 +833,8 @@ export default {
|
||||
ModalConfirm,
|
||||
ModalReport,
|
||||
Multiselect,
|
||||
BoxIcon,
|
||||
RightArrowIcon,
|
||||
},
|
||||
props: {
|
||||
project: {
|
||||
@@ -722,6 +877,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
primaryFile: {},
|
||||
alternateFile: {},
|
||||
version: {},
|
||||
|
||||
isEditing: false,
|
||||
@@ -738,6 +894,21 @@ export default {
|
||||
deleteFiles: [],
|
||||
replaceFile: null,
|
||||
|
||||
newFileTypes: [],
|
||||
oldFileTypes: [],
|
||||
fileTypes: [
|
||||
{
|
||||
display: 'Required resource pack',
|
||||
value: 'required-resource-pack',
|
||||
},
|
||||
{
|
||||
display: 'Optional resource pack',
|
||||
value: 'optional-resource-pack',
|
||||
},
|
||||
],
|
||||
|
||||
packageLoaders: ['forge', 'fabric', 'quilt'],
|
||||
|
||||
showKnownErrors: false,
|
||||
}
|
||||
},
|
||||
@@ -814,6 +985,7 @@ export default {
|
||||
acceptFileFromProjectType,
|
||||
reset() {
|
||||
this.primaryFile = {}
|
||||
this.alternateFile = {}
|
||||
this.version = {}
|
||||
|
||||
this.changelogViewMode = 'source'
|
||||
@@ -827,10 +999,14 @@ export default {
|
||||
this.newFiles = []
|
||||
this.deleteFiles = []
|
||||
this.replaceFile = null
|
||||
this.oldFileTypes = []
|
||||
this.newFileTypes = []
|
||||
|
||||
this.isEditing = false
|
||||
this.isCreating = false
|
||||
|
||||
this.packageLoaders = ['forge', 'fabric', 'quilt']
|
||||
|
||||
this.showKnownErrors = false
|
||||
},
|
||||
async setVersion() {
|
||||
@@ -916,6 +1092,9 @@ export default {
|
||||
this.version = JSON.parse(JSON.stringify(this.version))
|
||||
this.primaryFile =
|
||||
this.version.files.find((file) => file.primary) ?? this.version.files[0]
|
||||
this.alternateFile = this.version.files.find(
|
||||
(file) => file.file_type && file.file_type.includes('resource-pack')
|
||||
)
|
||||
|
||||
this.version.author_member = this.members.find(
|
||||
(x) => x.user.id === this.version.author_id
|
||||
@@ -948,6 +1127,10 @@ export default {
|
||||
}`
|
||||
: ''
|
||||
}
|
||||
|
||||
this.oldFileTypes = this.version.files.map((x) =>
|
||||
this.fileTypes.find((y) => y.value === x.file_type)
|
||||
)
|
||||
},
|
||||
async addDependency(
|
||||
dependencyAddMode,
|
||||
@@ -1037,12 +1220,24 @@ export default {
|
||||
|
||||
if (this.newFiles.length > 0 || this.replaceFile) {
|
||||
const formData = new FormData()
|
||||
const fileParts = this.newFiles.map((f, idx) => `${f.name}-${idx}`)
|
||||
|
||||
formData.append('data', JSON.stringify({}))
|
||||
formData.append(
|
||||
'data',
|
||||
JSON.stringify({
|
||||
file_types: this.newFileTypes.reduce(
|
||||
(acc, x, i) => ({
|
||||
...acc,
|
||||
[fileParts[i]]: x ? x.value : null,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
})
|
||||
)
|
||||
|
||||
for (let i = 0; i < this.newFiles.length; i++) {
|
||||
formData.append(
|
||||
this.newFiles[i].name.concat('-' + i),
|
||||
fileParts[i],
|
||||
new Blob([this.newFiles[i]]),
|
||||
this.newFiles[i].name
|
||||
)
|
||||
@@ -1079,6 +1274,13 @@ export default {
|
||||
loaders: this.version.loaders,
|
||||
primary_file: ['sha1', this.primaryFile.hashes.sha1],
|
||||
featured: this.version.featured,
|
||||
file_types: this.oldFileTypes.map((x, i) => {
|
||||
return {
|
||||
algorithm: 'sha1',
|
||||
hash: this.version.files[i].hashes.sha1,
|
||||
file_type: x ? x.value : null,
|
||||
}
|
||||
}),
|
||||
},
|
||||
this.$defaultHeaders()
|
||||
)
|
||||
@@ -1090,7 +1292,7 @@ export default {
|
||||
)
|
||||
}
|
||||
|
||||
const [versions, featuredVersions] = (
|
||||
const [versions, featuredVersions, dependencies] = (
|
||||
await Promise.all([
|
||||
this.$axios.get(
|
||||
`project/${this.version.project_id}/version`,
|
||||
@@ -1100,12 +1302,17 @@ export default {
|
||||
`project/${this.version.project_id}/version?featured=true`,
|
||||
this.$defaultHeaders()
|
||||
),
|
||||
this.$axios.get(
|
||||
`project/${this.version.project_id}/dependencies`,
|
||||
this.$defaultHeaders()
|
||||
),
|
||||
])
|
||||
).map((it) => it.data)
|
||||
|
||||
const newEditedVersions = this.$computeVersions(versions)
|
||||
this.$emit('update:versions', newEditedVersions)
|
||||
this.$emit('update:featuredVersions', featuredVersions)
|
||||
this.$emit('update:dependencies', dependencies)
|
||||
|
||||
await this.$router.replace(
|
||||
`/${this.project.project_type}/${
|
||||
@@ -1128,7 +1335,6 @@ export default {
|
||||
},
|
||||
async createVersion() {
|
||||
this.$nuxt.$loading.start()
|
||||
|
||||
if (this.fieldErrors) {
|
||||
this.showKnownErrors = true
|
||||
|
||||
@@ -1136,6 +1342,21 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await this.createVersionRaw(this.version)
|
||||
} catch (err) {
|
||||
this.$notify({
|
||||
group: 'main',
|
||||
title: 'An error occurred',
|
||||
text: err.response ? err.response.data.description : err,
|
||||
type: 'error',
|
||||
})
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
}
|
||||
|
||||
this.$nuxt.$loading.finish()
|
||||
},
|
||||
async createVersionRaw(version) {
|
||||
const formData = new FormData()
|
||||
|
||||
const fileParts = this.newFiles.map((f, idx) => `${f.name}-${idx}`)
|
||||
@@ -1144,20 +1365,27 @@ export default {
|
||||
}
|
||||
|
||||
if (this.project.project_type === 'resourcepack') {
|
||||
this.version.loaders = ['minecraft']
|
||||
version.loaders = ['minecraft']
|
||||
}
|
||||
|
||||
const newVersion = {
|
||||
project_id: this.version.project_id,
|
||||
project_id: version.project_id,
|
||||
file_parts: fileParts,
|
||||
version_number: this.version.version_number,
|
||||
version_title: this.version.name || this.version.version_number,
|
||||
version_body: this.version.changelog,
|
||||
dependencies: this.version.dependencies,
|
||||
game_versions: this.version.game_versions,
|
||||
loaders: this.version.loaders,
|
||||
release_channel: this.version.version_type,
|
||||
featured: this.version.featured,
|
||||
version_number: version.version_number,
|
||||
version_title: version.name || version.version_number,
|
||||
version_body: version.changelog,
|
||||
dependencies: version.dependencies,
|
||||
game_versions: version.game_versions,
|
||||
loaders: version.loaders,
|
||||
release_channel: version.version_type,
|
||||
featured: version.featured,
|
||||
file_types: this.newFileTypes.reduce(
|
||||
(acc, x, i) => ({
|
||||
...acc,
|
||||
[fileParts[this.replaceFile ? i + 1 : i]]: x ? x.value : null,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
}
|
||||
|
||||
formData.append('data', JSON.stringify(newVersion))
|
||||
@@ -1172,58 +1400,51 @@ export default {
|
||||
|
||||
for (let i = 0; i < this.newFiles.length; i++) {
|
||||
formData.append(
|
||||
fileParts[i],
|
||||
fileParts[this.replaceFile ? i + 1 : i],
|
||||
new Blob([this.newFiles[i]]),
|
||||
this.newFiles[i].name
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
const data = (
|
||||
await this.$axios({
|
||||
url: 'version',
|
||||
method: 'POST',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
Authorization: this.$auth.token,
|
||||
},
|
||||
})
|
||||
).data
|
||||
|
||||
const [versions, featuredVersions] = (
|
||||
await Promise.all([
|
||||
this.$axios.get(
|
||||
`project/${this.version.project_id}/version`,
|
||||
this.$defaultHeaders()
|
||||
),
|
||||
this.$axios.get(
|
||||
`project/${this.version.project_id}/version?featured=true`,
|
||||
this.$defaultHeaders()
|
||||
),
|
||||
])
|
||||
).map((it) => it.data)
|
||||
|
||||
const newCreatedVersions = this.$computeVersions(versions)
|
||||
this.$emit('update:versions', newCreatedVersions)
|
||||
this.$emit('update:featuredVersions', featuredVersions)
|
||||
|
||||
await this.$router.push(
|
||||
`/${this.project.project_type}/${
|
||||
this.project.slug ? this.project.slug : this.project.project_id
|
||||
}/version/${data.id}`
|
||||
)
|
||||
} catch (err) {
|
||||
this.$notify({
|
||||
group: 'main',
|
||||
title: 'An error occurred',
|
||||
text: err.response.data.description,
|
||||
type: 'error',
|
||||
const data = (
|
||||
await this.$axios({
|
||||
url: 'version',
|
||||
method: 'POST',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
Authorization: this.$auth.token,
|
||||
},
|
||||
})
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
}
|
||||
).data
|
||||
|
||||
this.$nuxt.$loading.finish()
|
||||
const [versions, featuredVersions, dependencies] = (
|
||||
await Promise.all([
|
||||
this.$axios.get(
|
||||
`project/${this.version.project_id}/version`,
|
||||
this.$defaultHeaders()
|
||||
),
|
||||
this.$axios.get(
|
||||
`project/${this.version.project_id}/version?featured=true`,
|
||||
this.$defaultHeaders()
|
||||
),
|
||||
this.$axios.get(
|
||||
`project/${this.version.project_id}/dependencies`,
|
||||
this.$defaultHeaders()
|
||||
),
|
||||
])
|
||||
).map((it) => it.data)
|
||||
|
||||
const newCreatedVersions = this.$computeVersions(versions)
|
||||
this.$emit('update:versions', newCreatedVersions)
|
||||
this.$emit('update:featuredVersions', featuredVersions)
|
||||
this.$emit('update:dependencies', dependencies)
|
||||
|
||||
await this.$router.push(
|
||||
`/${this.project.project_type}/${
|
||||
this.project.slug ? this.project.slug : this.project.project_id
|
||||
}/version/${data.id}`
|
||||
)
|
||||
},
|
||||
async deleteVersion() {
|
||||
this.$nuxt.$loading.start()
|
||||
@@ -1238,6 +1459,56 @@ export default {
|
||||
)
|
||||
this.$nuxt.$loading.finish()
|
||||
},
|
||||
async createDataPackVersion() {
|
||||
this.$nuxt.$loading.start()
|
||||
try {
|
||||
const blob = await createDataPackVersion(
|
||||
this.project,
|
||||
this.version,
|
||||
this.primaryFile,
|
||||
this.members,
|
||||
this.$tag.gameVersions,
|
||||
this.packageLoaders
|
||||
)
|
||||
|
||||
this.newFiles = []
|
||||
this.newFileTypes = []
|
||||
this.replaceFile = new File(
|
||||
[blob],
|
||||
`${this.project.slug}-${this.version.version_number}.jar`
|
||||
)
|
||||
|
||||
await this.createVersionRaw({
|
||||
project_id: this.project.id,
|
||||
author_id: this.currentMember.user.id,
|
||||
name: this.version.name,
|
||||
version_number: `${this.version.version_number}+mod`,
|
||||
changelog: this.version.changelog,
|
||||
version_type: this.version.version_type,
|
||||
dependencies: this.version.dependencies,
|
||||
game_versions: this.version.game_versions,
|
||||
loaders: this.packageLoaders,
|
||||
featured: this.version.featured,
|
||||
})
|
||||
|
||||
this.$refs.modal_package_mod.hide()
|
||||
|
||||
this.$notify({
|
||||
group: 'main',
|
||||
title: 'Packaging Success',
|
||||
text: 'Your data pack was successfully packaged as a mod! Make sure to playtest to check for errors.',
|
||||
type: 'success',
|
||||
})
|
||||
} catch (err) {
|
||||
this.$notify({
|
||||
group: 'main',
|
||||
title: 'An error occurred',
|
||||
text: err.response ? err.response.data.description : err,
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
this.$nuxt.$loading.finish()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1383,8 +1654,7 @@ export default {
|
||||
}
|
||||
|
||||
.filename {
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
word-wrap: anywhere;
|
||||
}
|
||||
|
||||
.file-size {
|
||||
@@ -1392,6 +1662,19 @@ export default {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.file-type {
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.raised-multiselect {
|
||||
display: none;
|
||||
margin: 0 0.5rem;
|
||||
height: 40px;
|
||||
max-height: 40px;
|
||||
min-width: 235px;
|
||||
}
|
||||
|
||||
.iconified-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
@@ -1399,6 +1682,13 @@ export default {
|
||||
&:not(:nth-child(2)) {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
// TODO: Make file type editing work on mobile
|
||||
@media (min-width: 600px) {
|
||||
.raised-multiselect {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.additional-files {
|
||||
@@ -1454,4 +1744,23 @@ export default {
|
||||
.separator {
|
||||
margin: var(--spacing-card-sm) 0;
|
||||
}
|
||||
|
||||
.modal-package-mod {
|
||||
padding: var(--spacing-card-bg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.markdown-body {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
max-width: 20rem;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
margin-left: auto;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="card">
|
||||
<h1>About</h1>
|
||||
<p>
|
||||
Founded in 2020, Modrinth was created to provide modders with an open
|
||||
and intuitive platform to publish their projects on.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Our primary goal is to be as open as possible, with all our code being
|
||||
<a :target="$external()" href="https://github.com/modrinth">
|
||||
open source</a
|
||||
>, while giving back to the modding community as much as possible.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
While we still are in beta, we hope we can be a major modding platform
|
||||
for all modders.
|
||||
</p>
|
||||
<h2>How does Modrinth work?</h2>
|
||||
<p>
|
||||
Modrinth is not just a website: it is made of several different
|
||||
components that all come together to make a fast and flexible modding
|
||||
platform.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
On the technical level, Modrinth is made up of two main components: the
|
||||
Rust-based backend named
|
||||
<a :target="$external()" href="https://github.com/modrinth/labrinth"
|
||||
>Labrinth</a
|
||||
>, and the Vue-based frontend named
|
||||
<a :target="$external()" href="https://github.com/modrinth/knossos">
|
||||
Knossos</a
|
||||
>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Additionally, some other custom-created resources exist, including but
|
||||
not limited to:
|
||||
<a :target="$external()" href="https://github.com/modrinth/minotaur"
|
||||
>Minotaur</a
|
||||
>, a Gradle plugin for easily publishing mods to Modrinth, and
|
||||
<a :target="$external()" href="https://github.com/modrinth/minos">
|
||||
Minos</a
|
||||
>, an authentication provider. All of Modrinth's code can be found on
|
||||
<a :target="$external()" href="https://github.com/modrinth"
|
||||
>our GitHub page</a
|
||||
>.
|
||||
</p>
|
||||
<h2>Backend Documentation</h2>
|
||||
<p>
|
||||
Documentation for the Modrinth API (Labrinth) can be found on the GitHub
|
||||
repository's wiki
|
||||
<a :target="$external()" href="https://docs.modrinth.com">here</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
auth: false,
|
||||
head: {
|
||||
title: 'About - Modrinth',
|
||||
meta: [
|
||||
{
|
||||
hid: 'apple-mobile-web-app-title',
|
||||
name: 'apple-mobile-web-app-title',
|
||||
content: 'About',
|
||||
},
|
||||
{
|
||||
hid: 'og:title',
|
||||
name: 'og:title',
|
||||
content: 'About',
|
||||
},
|
||||
{
|
||||
hid: 'og:url',
|
||||
name: 'og:url',
|
||||
content: `https://modrinth.com/about`,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.main {
|
||||
margin: var(--spacing-card-sm) auto;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: var(--color-link);
|
||||
}
|
||||
</style>
|
||||
@@ -126,7 +126,7 @@
|
||||
<div class="title">
|
||||
<h3>
|
||||
{{ item.item_type }}
|
||||
<a :href="item.url">{{ item.item_id }}</a>
|
||||
<nuxt-link :to="item.url">{{ item.item_id }}</nuxt-link>
|
||||
</h3>
|
||||
reported by
|
||||
<a :href="`/user/${item.reporter}`">{{ item.reporter }}</a>
|
||||
|
||||
@@ -78,7 +78,9 @@
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
v-if="projectType.id !== 'resourcepack'"
|
||||
v-if="
|
||||
projectType.id !== 'resourcepack' && projectType.id !== 'datapack'
|
||||
"
|
||||
aria-label="Loader filters"
|
||||
>
|
||||
<h3
|
||||
@@ -101,15 +103,15 @@
|
||||
x.name !== 'quilt'
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (projectType.id === 'mod' && showAllLoaders) {
|
||||
} else if (projectType.id === 'mod' && showAllLoaders) {
|
||||
return $tag.loaderData.modLoaders.includes(x.name)
|
||||
} else if (projectType.id === 'plugin') {
|
||||
return $tag.loaderData.pluginLoaders.includes(x.name)
|
||||
} else if (projectType.id === 'datapack') {
|
||||
return $tag.loaderData.dataPackLoaders.includes(x.name)
|
||||
} else {
|
||||
return x.supported_project_types.includes(projectType.actual)
|
||||
}
|
||||
|
||||
return projectType.id === 'plugin'
|
||||
? $tag.loaderData.pluginLoaders.includes(x.name)
|
||||
: x.supported_project_types.includes(projectType.actual)
|
||||
})"
|
||||
:key="loader.name"
|
||||
ref="loaderFilters"
|
||||
@@ -158,7 +160,9 @@
|
||||
</section>
|
||||
<section
|
||||
v-if="
|
||||
!['resourcepack', 'plugin', 'shader'].includes(projectType.id)
|
||||
!['resourcepack', 'plugin', 'shader', 'datapack'].includes(
|
||||
projectType.id
|
||||
)
|
||||
"
|
||||
aria-label="Environment filters"
|
||||
>
|
||||
@@ -376,6 +380,9 @@
|
||||
:categories="result.display_categories"
|
||||
:search="true"
|
||||
:show-updated-date="sortType.name !== 'newest'"
|
||||
:hide-loaders="
|
||||
['resourcepack', 'datapack'].includes(projectType.id)
|
||||
"
|
||||
/>
|
||||
<div v-if="results && results.length === 0" class="no-results">
|
||||
<p>No results found for your query!</p>
|
||||
@@ -714,6 +721,12 @@ export default {
|
||||
(x) => `categories:'${encodeURIComponent(x)}'`
|
||||
)
|
||||
)
|
||||
} else if (this.projectType.id === 'datapack') {
|
||||
formattedFacets.push(
|
||||
this.$tag.loaderData.dataPackLoaders.map(
|
||||
(x) => `categories:'${encodeURIComponent(x)}'`
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (this.selectedVersions.length > 0) {
|
||||
|
||||
11
pages/search/datapacks.vue
Normal file
11
pages/search/datapacks.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Datapacks',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -161,6 +161,7 @@ export default {
|
||||
resourcepack: 'gallery',
|
||||
modpack: 'list',
|
||||
shader: 'gallery',
|
||||
datapack: 'list',
|
||||
user: 'list',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
},
|
||||
...projectTypes.map((x) => {
|
||||
return {
|
||||
label: x === 'resourcepack' ? 'Resource Packs' : x + 's',
|
||||
label: $formatProjectType(x) + 's',
|
||||
href: x,
|
||||
}
|
||||
}),
|
||||
@@ -326,13 +326,47 @@ export default {
|
||||
}
|
||||
|
||||
let gitHubUser = {}
|
||||
|
||||
let versions = []
|
||||
try {
|
||||
gitHubUser = (
|
||||
await data.$axios.get(`https://api.github.com/user/` + user.github_id)
|
||||
).data
|
||||
const [gitHubUserData, versionsData] = (
|
||||
await Promise.all([
|
||||
data.$axios.get(`https://api.github.com/user/` + user.github_id),
|
||||
data.$axios.get(
|
||||
`versions?ids=${JSON.stringify(
|
||||
[].concat.apply(
|
||||
[],
|
||||
projects.map((x) => x.versions)
|
||||
)
|
||||
)}`
|
||||
),
|
||||
])
|
||||
).map((it) => it.data)
|
||||
gitHubUser = gitHubUserData
|
||||
versions = versionsData
|
||||
} catch {}
|
||||
|
||||
for (const version of versions) {
|
||||
const projectIndex = projects.findIndex(
|
||||
(x) => x.id === version.project_id
|
||||
)
|
||||
if (projects[projectIndex].loaders) {
|
||||
for (const loader of version.loaders) {
|
||||
if (!projects[projectIndex].loaders.includes(loader)) {
|
||||
projects[projectIndex].loaders.push(loader)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
projects[projectIndex].loaders = version.loaders
|
||||
}
|
||||
}
|
||||
for (const project of projects) {
|
||||
project.categories = project.categories.concat(project.loaders)
|
||||
project.project_type = data.$getProjectTypeForUrl(
|
||||
project.project_type,
|
||||
project.categories
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
user,
|
||||
projects,
|
||||
|
||||
Reference in New Issue
Block a user