You've already forked AstralRinth
forked from didirus/AstralRinth
Mod creation WIP
This commit is contained in:
@@ -1,38 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ins
|
|
||||||
class="adsbygoogle"
|
|
||||||
:data-ad-client="adClient"
|
|
||||||
:data-ad-slot="adSlot"
|
|
||||||
:data-ad-format="adFormat"
|
|
||||||
:style="adStyle"
|
|
||||||
></ins>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'GoogleAd',
|
|
||||||
props: {
|
|
||||||
adClient: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
adSlot: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
adFormat: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: 'auto',
|
|
||||||
},
|
|
||||||
adStyle: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
default: 'display: block',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
;(window.adsbygoogle = window.adsbygoogle || []).push({})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<h2 class="mod-name">
|
<h2 class="mod-name">
|
||||||
<a :href="pageUrl">{{ name }}</a>
|
<a :href="pageUrl">{{ name }}</a>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="author">
|
<p class="author" v-if="author">
|
||||||
by <a :href="authorUrl">{{ author }}</a>
|
by <a :href="authorUrl">{{ author }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<polyline points="7 10 12 15 17 10"></polyline>
|
<polyline points="7 10 12 15 17 10"></polyline>
|
||||||
<line x1="12" y1="15" x2="12" y2="3"></line>
|
<line x1="12" y1="15" x2="12" y2="3"></line>
|
||||||
</svg>
|
</svg>
|
||||||
<p>{{ downloads }}</p>
|
<p>{{ formatNumber(downloads) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="result-image columns">
|
<div class="result-image columns">
|
||||||
<svg viewBox="0 0 16 16" fill="#099fef">
|
<svg viewBox="0 0 16 16" fill="#099fef">
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<p>{{ $dayjs(createdAt).fromNow() }}</p>
|
<p>{{ $dayjs(createdAt).fromNow() }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="result-image columns">
|
<div class="result-image columns" v-if="updatedAt">
|
||||||
<svg
|
<svg
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
@@ -195,7 +195,7 @@ export default {
|
|||||||
},
|
},
|
||||||
author: {
|
author: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'Author',
|
default: null,
|
||||||
},
|
},
|
||||||
description: {
|
description: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -223,11 +223,11 @@ export default {
|
|||||||
},
|
},
|
||||||
updatedAt: {
|
updatedAt: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '0000-00-00',
|
default: null,
|
||||||
},
|
},
|
||||||
latestVersion: {
|
latestVersion: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '1.16.2',
|
default: 'None',
|
||||||
},
|
},
|
||||||
categories: {
|
categories: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -240,6 +240,11 @@ export default {
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
formatNumber(x) {
|
||||||
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -80,13 +80,7 @@ export default {
|
|||||||
'https://fonts.googleapis.com/css2?family=Montserrat+Alternates:wght@600&display=swap',
|
'https://fonts.googleapis.com/css2?family=Montserrat+Alternates:wght@600&display=swap',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
script: [
|
script: [],
|
||||||
{
|
|
||||||
src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
|
|
||||||
'data-ad-client': 'ca-pub-4800120742989028',
|
|
||||||
async: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
|
|
||||||
vue: {
|
vue: {
|
||||||
|
|||||||
@@ -41,11 +41,16 @@ import axios from 'axios'
|
|||||||
export default {
|
export default {
|
||||||
async fetch() {
|
async fetch() {
|
||||||
try {
|
try {
|
||||||
const res = await axios.get(
|
let res = await axios.get(
|
||||||
`https://api.modrinth.com/api/v1/${this.$auth.user.id}/mods`
|
`https://api.modrinth.com/api/v1/user/${this.$auth.user.id}/mods`
|
||||||
)
|
)
|
||||||
|
|
||||||
this.mods = res.data
|
if (res.data) {
|
||||||
|
res = await axios.get(
|
||||||
|
`https://api.modrinth.com/api/v1/mods?ids=${JSON.stringify(res.data)}`
|
||||||
|
)
|
||||||
|
this.mods = res.data
|
||||||
|
}
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -1,16 +1,91 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h2>Create Mod</h2>
|
<h2>Create Mod</h2>
|
||||||
<input v-model="name" type="text" />
|
<section>
|
||||||
<input v-model="namespace" type="text" />
|
<h3>Initial Data</h3>
|
||||||
<input v-model="description" type="text" />
|
<div class="initial">
|
||||||
<div class="editor">
|
<div class="image-data">
|
||||||
|
<img
|
||||||
|
:src="
|
||||||
|
previewImage
|
||||||
|
? previewImage
|
||||||
|
: 'https://i0.kym-cdn.com/entries/icons/facebook/000/013/564/aP2dv.gif'
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
id="file"
|
||||||
|
class="file-input"
|
||||||
|
type="file"
|
||||||
|
accept="image/x-png,image/gif,image/jpeg"
|
||||||
|
@change="showPreviewImage"
|
||||||
|
/>
|
||||||
|
<label for="file">Upload Icon</label>
|
||||||
|
</div>
|
||||||
|
<div class="mod-data">
|
||||||
|
<label class="required" title="The name of your mod"> Name </label>
|
||||||
|
<input v-model="name" type="text" placeholder="Example Mod" />
|
||||||
|
<label
|
||||||
|
class="required"
|
||||||
|
title="The namespace of your mod, an example is com.example.mod"
|
||||||
|
>
|
||||||
|
Namespace
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="namespace"
|
||||||
|
type="text"
|
||||||
|
placeholder="com.example.examplemod"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="required"
|
||||||
|
title="The short-form description of your mod. This shows up in searches"
|
||||||
|
>
|
||||||
|
Short Description
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
v-model="description"
|
||||||
|
type="text"
|
||||||
|
placeholder="An example mod which does example stuff!"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="editor">
|
||||||
|
<h3>Mod Body</h3>
|
||||||
|
<p>
|
||||||
|
You can type the of the long form of your description here. This editor
|
||||||
|
supports markdown. You can find the syntax
|
||||||
|
<a href="https://github.com/dimerapp/markdown/blob/develop/syntax.md"
|
||||||
|
>here</a
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
<textarea v-model="body"></textarea>
|
<textarea v-model="body"></textarea>
|
||||||
<div v-html="$md.render(body)"></div>
|
<div v-html="$md.render(body)"></div>
|
||||||
</div>
|
</section>
|
||||||
<input v-model="issues_url" type="text" />
|
<section>
|
||||||
<input v-model="source_url" type="text" />
|
<h3>Versions</h3>
|
||||||
<input v-model="wiki_url" type="text" />
|
</section>
|
||||||
|
<section>
|
||||||
|
<h3>Extras</h3>
|
||||||
|
<div class="extras">
|
||||||
|
<label
|
||||||
|
title="A link where users can go to report bugs, issues, and concerns about your mod."
|
||||||
|
>
|
||||||
|
Issues URL
|
||||||
|
<input v-model="issues_url" type="text" placeholder="Optional" />
|
||||||
|
</label>
|
||||||
|
<label title="A link to a page/repository containing the source code ">
|
||||||
|
Source Code Link
|
||||||
|
<input v-model="source_url" type="text" placeholder="Optional" />
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
title="A link to a page containing information, documentation, and help for the mod. (Optional)"
|
||||||
|
>
|
||||||
|
Wiki Link
|
||||||
|
<input v-model="wiki_url" type="text" placeholder="Optional" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<button @click="createMod">Create mod</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -20,6 +95,7 @@ import axios from 'axios'
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
previewImage: null,
|
||||||
name: '',
|
name: '',
|
||||||
namespace: '',
|
namespace: '',
|
||||||
description: '',
|
description: '',
|
||||||
@@ -30,6 +106,7 @@ export default {
|
|||||||
issues_url: null,
|
issues_url: null,
|
||||||
source_url: null,
|
source_url: null,
|
||||||
wiki_url: null,
|
wiki_url: null,
|
||||||
|
icon: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -58,6 +135,9 @@ export default {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (this.icon)
|
||||||
|
formData.append('icon', new Blob([this.icon]), this.icon.name)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await axios({
|
const result = await axios({
|
||||||
url: 'https://api.modrinth.com/api/v1/mod',
|
url: 'https://api.modrinth.com/api/v1/mod',
|
||||||
@@ -65,6 +145,7 @@ export default {
|
|||||||
data: formData,
|
data: formData,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'multipart/form-data',
|
'Content-Type': 'multipart/form-data',
|
||||||
|
Authorization: this.$auth.getToken('local'),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -75,23 +156,96 @@ export default {
|
|||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
compileBody() {
|
showPreviewImage(e) {
|
||||||
// this.compiledBody = DomPurify.sanitize(marked(this.body))
|
const reader = new FileReader()
|
||||||
|
this.icon = e.target.files[0]
|
||||||
|
reader.readAsDataURL(this.icon)
|
||||||
|
|
||||||
|
reader.onload = (event) => {
|
||||||
|
this.previewImage = event.target.result
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
section {
|
||||||
|
box-shadow: 0 2px 3px 1px var(--color-grey-2);
|
||||||
|
margin: 50px 25px;
|
||||||
|
padding: 5px 20px 20px 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: var(--color-bg);
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 200px;
|
width: 100%;
|
||||||
margin-right: auto;
|
padding: 0.5rem 5px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.initial {
|
||||||
|
display: flex;
|
||||||
|
.image-data {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
img {
|
||||||
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
height: 85%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
[type='file'] {
|
||||||
|
border: 0;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
position: absolute !important;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 1px;
|
||||||
|
|
||||||
|
+ label {
|
||||||
|
border-radius: 5px;
|
||||||
|
color: var(--color-grey-5);
|
||||||
|
background-color: var(--color-grey-1);
|
||||||
|
padding: 10px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus + label,
|
||||||
|
+ label:hover,
|
||||||
|
&:focus + label {
|
||||||
|
background-color: var(--color-grey-2);
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mod-data {
|
||||||
|
flex: 4;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.editor {
|
.editor {
|
||||||
width: 100%;
|
width: calc(100% - 90px);
|
||||||
min-height: 500px;
|
min-height: 500px;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
width: calc(50% - 50px);
|
width: calc(50% - 50px);
|
||||||
@@ -110,10 +264,36 @@ input {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
min-height: 540px;
|
min-height: 540px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 50%;
|
width: calc(50%);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
background-color: var(--color-grey-2);
|
background-color: var(--color-grey-2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
float: right;
|
||||||
|
margin: -10px 25px 20px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
outline: none;
|
||||||
|
color: var(--color-grey-5);
|
||||||
|
background-color: var(--color-grey-1);
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--color-grey-2);
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.extras {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.required:after {
|
||||||
|
content: ' *';
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
:latest-version="result.versions[0]"
|
:latest-version="result.versions[0]"
|
||||||
:created-at="result.date_created"
|
:created-at="result.date_created"
|
||||||
:updated-at="result.date_modified"
|
:updated-at="result.date_modified"
|
||||||
:downloads="formatNumber(result.downloads)"
|
:downloads="result.downloads.toString()"
|
||||||
:icon-url="result.icon_url"
|
:icon-url="result.icon_url"
|
||||||
:author-url="result.author_url"
|
:author-url="result.author_url"
|
||||||
:page-url="result.page_url"
|
:page-url="result.page_url"
|
||||||
@@ -469,9 +469,6 @@ export default {
|
|||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
formatNumber(x) {
|
|
||||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|
||||||
},
|
|
||||||
toggleFiltersMenu() {
|
toggleFiltersMenu() {
|
||||||
const filters = document.getElementById('filters')
|
const filters = document.getElementById('filters')
|
||||||
const currentlyActive = filters.className === 'filters active'
|
const currentlyActive = filters.className === 'filters active'
|
||||||
|
|||||||
@@ -1,14 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<img :src="user.avatar_url" />
|
<img :src="user.avatar_url" />
|
||||||
|
<div>
|
||||||
|
<SearchResult
|
||||||
|
v-for="(result, index) in mods"
|
||||||
|
:id="result.mod_id"
|
||||||
|
:key="result.mod_id"
|
||||||
|
:name="result.title"
|
||||||
|
:description="result.description"
|
||||||
|
:latest-version="result.versions[0]"
|
||||||
|
:created-at="result.published"
|
||||||
|
:downloads="result.downloads.toString()"
|
||||||
|
:icon-url="result.icon_url"
|
||||||
|
:author-url="result.author_url"
|
||||||
|
:page-url="result.page_url"
|
||||||
|
:categories="result.categories"
|
||||||
|
:is-ad="index === -1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import SearchResult from '@/components/ModResult'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
auth: false,
|
auth: false,
|
||||||
|
components: {
|
||||||
|
SearchResult,
|
||||||
|
},
|
||||||
async asyncData(data) {
|
async asyncData(data) {
|
||||||
let res = await axios.get(
|
let res = await axios.get(
|
||||||
`https://api.modrinth.com/api/v1/user/${data.params.id}`
|
`https://api.modrinth.com/api/v1/user/${data.params.id}`
|
||||||
@@ -21,7 +42,7 @@ export default {
|
|||||||
)
|
)
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
res = await axios.get(
|
res = await axios.get(
|
||||||
`https://api.modrinth.com/api/v1/mods/?ids=${JSON.stringify(res.data)}`
|
`https://api.modrinth.com/api/v1/mods?ids=${JSON.stringify(res.data)}`
|
||||||
)
|
)
|
||||||
mods = res.data
|
mods = res.data
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user