You've already forked AstralRinth
forked from didirus/AstralRinth
Fix creation + make it more accessible. Also added User Pages. User Context Menu moved to settings cog
This commit is contained in:
1
assets/images/utils/exit.svg
Normal file
1
assets/images/utils/exit.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
|
||||||
|
After Width: | Height: | Size: 256 B |
@@ -1 +0,0 @@
|
|||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline><polyline points="7 3 7 8 15 8"></polyline></svg>
|
|
||||||
|
Before Width: | Height: | Size: 306 B |
1
assets/images/utils/settings.svg
Normal file
1
assets/images/utils/settings.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 921 B |
@@ -34,6 +34,11 @@
|
|||||||
letter-spacing: 0.02rem;
|
letter-spacing: 0.02rem;
|
||||||
padding: 0.25rem 0.5rem;
|
padding: 0.25rem 0.5rem;
|
||||||
|
|
||||||
|
&.gray {
|
||||||
|
background-color: #c8c1c1;
|
||||||
|
color: #646161;
|
||||||
|
}
|
||||||
|
|
||||||
&.red {
|
&.red {
|
||||||
background-color: #fed7d7;
|
background-color: #fed7d7;
|
||||||
color: #9b2c2c;
|
color: #9b2c2c;
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
.rounded-md {
|
.rounded-md {
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="result rows">
|
<div class="result rows">
|
||||||
<img class="result-icon" :src="iconUrl" />
|
<img
|
||||||
|
class="result-icon"
|
||||||
|
:src="
|
||||||
|
iconUrl
|
||||||
|
? iconUrl
|
||||||
|
: 'https://cdn.modrinth.com/file/modrinth/placeholder.png'
|
||||||
|
"
|
||||||
|
:alt="name"
|
||||||
|
/>
|
||||||
<div class="rows result-name-author">
|
<div class="rows result-name-author">
|
||||||
<h2 class="mod-name">
|
<h2 class="mod-name">
|
||||||
<a :href="pageUrl">{{ name }}</a>
|
<a :href="pageUrl">{{ name }}</a>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="author" v-if="author">
|
<p v-if="author" class="author">
|
||||||
by <a :href="authorUrl">{{ author }}</a>
|
by <a :href="authorUrl">{{ author }}</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,7 +55,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<p>{{ $dayjs(createdAt).fromNow() }}</p>
|
<p>{{ $dayjs(createdAt).fromNow() }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="result-image columns" v-if="updatedAt">
|
<div v-if="updatedAt" class="result-image columns">
|
||||||
<svg
|
<svg
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<aside>
|
<aside>
|
||||||
|
<label class="hidden" for="toggle-nav-menu">Toggle Nav Menu</label>
|
||||||
<input
|
<input
|
||||||
|
id="toggle-nav-menu"
|
||||||
class="hamburger-button"
|
class="hamburger-button"
|
||||||
alt="Open navigation menu"
|
alt="Open navigation menu"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@@ -10,7 +12,7 @@
|
|||||||
<!-- TODO: Probably shouldn't be a Unicode symbol -->
|
<!-- TODO: Probably shouldn't be a Unicode symbol -->
|
||||||
<div class="hamburger-icon">☰</div>
|
<div class="hamburger-icon">☰</div>
|
||||||
<nuxt-link to="/" class="logo-wrapper">
|
<nuxt-link to="/" class="logo-wrapper">
|
||||||
<img class="logo" src="~/assets/images/logo.svg" />
|
<img class="logo" src="~/assets/images/logo.svg" alt="modrinth-logo" />
|
||||||
<span class="name">modrinth</span>
|
<span class="name">modrinth</span>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nav>
|
<nav>
|
||||||
@@ -134,41 +136,31 @@
|
|||||||
this.$route.path
|
this.$route.path
|
||||||
"
|
"
|
||||||
class="log-in-button"
|
class="log-in-button"
|
||||||
>Log In</a
|
|
||||||
>
|
>
|
||||||
|
Log In
|
||||||
|
</a>
|
||||||
<div v-if="this.$auth.loggedIn" class="avatar">
|
<div v-if="this.$auth.loggedIn" class="avatar">
|
||||||
<img
|
<img :src="this.$auth.user.avatar_url" alt="avatar" />
|
||||||
:src="this.$auth.user.avatar_url"
|
<span> {{ this.$auth.user.username }} </span>
|
||||||
alt="avatar"
|
</div>
|
||||||
@click="showPopup = !showPopup"
|
<div v-if="this.$auth.loggedIn" class="notifications">
|
||||||
/>
|
|
||||||
<div v-if="showPopup" class="user-actions-popup">
|
<div v-if="showPopup" class="user-actions-popup">
|
||||||
<div class="popup-inner">
|
<div class="popup-inner">
|
||||||
<p>
|
<p>
|
||||||
Modrinth ID: <strong>{{ this.$auth.user.id }}</strong>
|
Modrinth ID: <strong>{{ this.$auth.user.id }}</strong>
|
||||||
</p>
|
</p>
|
||||||
<hr />
|
<hr />
|
||||||
<p>My profile</p>
|
<p class="hover">
|
||||||
<p>My teams</p>
|
<nuxt-link :to="'/user/' + this.$auth.user.id">
|
||||||
|
My profile
|
||||||
|
</nuxt-link>
|
||||||
|
</p>
|
||||||
|
<p class="hover">My teams</p>
|
||||||
<hr />
|
<hr />
|
||||||
<p>Settings</p>
|
<p class="hover" @click="logout">Logout</p>
|
||||||
<p @click="logout">Logout</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span> {{ this.$auth.user.username }} </span>
|
<SettingsIcon @click="showPopup = !showPopup" />
|
||||||
</div>
|
|
||||||
<div v-if="this.$auth.loggedIn" class="notifications">
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" />
|
|
||||||
<path d="M13.73 21a2 2 0 0 1-3.46 0" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="theme">
|
<div class="theme">
|
||||||
<svg
|
<svg
|
||||||
@@ -214,29 +206,18 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
<main>
|
<main>
|
||||||
<!-- <header>
|
|
||||||
<div class="search-wrapper">
|
|
||||||
<input type="search" name="search" id="search" placeholder="Search...">
|
|
||||||
<!/-- Icon follows and not precedes the input so we can target it with CSS' ~ selector --/>
|
|
||||||
<svg
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round">
|
|
||||||
<circle cx="11" cy="11" r="8"/>
|
|
||||||
<line x1="21" y1="21" x2="16.65" y2="16.65"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</header> -->
|
|
||||||
<nuxt />
|
<nuxt />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import SettingsIcon from '~/assets/images/utils/settings.svg?inline'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
SettingsIcon,
|
||||||
|
},
|
||||||
async fetch() {
|
async fetch() {
|
||||||
if (this.$route.query.code)
|
if (this.$route.query.code)
|
||||||
await this.$auth.setUserToken(this.$route.query.code)
|
await this.$auth.setUserToken(this.$route.query.code)
|
||||||
@@ -420,7 +401,6 @@ export default {
|
|||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
img {
|
img {
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
@@ -441,11 +421,17 @@ export default {
|
|||||||
margin-left: 2.5rem;
|
margin-left: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notifications {
|
||||||
|
svg {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.user-actions-popup {
|
.user-actions-popup {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.popup-inner {
|
.popup-inner {
|
||||||
width: 140px;
|
width: 120px;
|
||||||
border: 2px var(--color-grey-2) solid;
|
border: 2px var(--color-grey-2) solid;
|
||||||
background-color: var(--color-bg);
|
background-color: var(--color-bg);
|
||||||
color: var(--color-grey-5);
|
color: var(--color-grey-5);
|
||||||
@@ -462,12 +448,15 @@ export default {
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
cursor: pointer;
|
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
color: var(--color-text-inverted);
|
|
||||||
background-color: var(--color-brand);
|
background-color: var(--color-brand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -476,7 +465,7 @@ export default {
|
|||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100%;
|
top: 100%;
|
||||||
right: 80%;
|
left: 45%;
|
||||||
border-width: 7px;
|
border-width: 7px;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: var(--color-grey-2) transparent transparent
|
border-color: var(--color-grey-2) transparent transparent
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ export default {
|
|||||||
** See https://nuxtjs.org/api/configuration-head
|
** See https://nuxtjs.org/api/configuration-head
|
||||||
*/
|
*/
|
||||||
head: {
|
head: {
|
||||||
|
htmlAttrs: {
|
||||||
|
lang: 'en',
|
||||||
|
},
|
||||||
title: 'Modrinth',
|
title: 'Modrinth',
|
||||||
meta: [
|
meta: [
|
||||||
{ charset: 'utf-8' },
|
{ charset: 'utf-8' },
|
||||||
@@ -131,7 +134,7 @@ export default {
|
|||||||
ackee: {
|
ackee: {
|
||||||
server: 'https://analytics.modrinth.com',
|
server: 'https://analytics.modrinth.com',
|
||||||
domainId: '1840cc3a-64b1-431e-97a4-c122bb64d4c0',
|
domainId: '1840cc3a-64b1-431e-97a4-c122bb64d4c0',
|
||||||
ignoreLocalhost: false,
|
ignoreLocalhost: true,
|
||||||
detailed: true,
|
detailed: true,
|
||||||
},
|
},
|
||||||
robots: {
|
robots: {
|
||||||
|
|||||||
@@ -26,7 +26,26 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>{{ mod.title }}</td>
|
<td>{{ mod.title }}</td>
|
||||||
<td>Owner</td>
|
<td>Owner</td>
|
||||||
<td><span class="badge green">Active</span></td>
|
<td>
|
||||||
|
<span v-if="mod.status === 'approved'" class="badge green">
|
||||||
|
Approved
|
||||||
|
</span>
|
||||||
|
<span v-if="mod.status === 'rejected'" class="badge red">
|
||||||
|
Rejected
|
||||||
|
</span>
|
||||||
|
<span v-if="mod.status === 'draft'" class="badge yellow">
|
||||||
|
Draft
|
||||||
|
</span>
|
||||||
|
<span v-if="mod.status === 'processing'" class="badge yellow">
|
||||||
|
Processing
|
||||||
|
</span>
|
||||||
|
<span v-if="mod.status === 'unlisted'" class="badge gray">
|
||||||
|
Unlisted
|
||||||
|
</span>
|
||||||
|
<span v-if="mod.status === 'unknown'" class="badge gray">
|
||||||
|
Unknown
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
<td>{{ mod.downloads }}</td>
|
<td>{{ mod.downloads }}</td>
|
||||||
<td>{{ $dayjs(mod.published).format('YYYY-MM-DD') }}</td>
|
<td>{{ $dayjs(mod.published).format('YYYY-MM-DD') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
:src="
|
:src="
|
||||||
previewImage
|
previewImage
|
||||||
? previewImage
|
? previewImage
|
||||||
: 'https://i0.kym-cdn.com/entries/icons/facebook/000/013/564/aP2dv.gif'
|
: 'https://cdn.modrinth.com/file/modrinth/placeholder.png'
|
||||||
"
|
"
|
||||||
|
alt="preview-image"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
id="icon-file"
|
id="icon-file"
|
||||||
@@ -89,7 +90,7 @@
|
|||||||
You can type the of the long form of your description here. This editor
|
You can type the of the long form of your description here. This editor
|
||||||
supports markdown. You can find the syntax
|
supports markdown. You can find the syntax
|
||||||
<a
|
<a
|
||||||
href="https://github.com/dimerapp/markdown/blob/develop/syntax.md"
|
href="https://guides.github.com/features/mastering-markdown/"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>here</a
|
>here</a
|
||||||
@@ -99,14 +100,22 @@
|
|||||||
<div v-html="compiledBody"></div>
|
<div v-html="compiledBody"></div>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<div v-if="currentVersionIndex > -1" class="create-version-popup"></div>
|
<button
|
||||||
|
v-if="currentVersionIndex > -1"
|
||||||
|
class="create-version-popup"
|
||||||
|
@click="currentVersionIndex = -1"
|
||||||
|
/>
|
||||||
<div v-if="currentVersionIndex > -1" class="create-version-popup-body">
|
<div v-if="currentVersionIndex > -1" class="create-version-popup-body">
|
||||||
<div class="versions-header">
|
<div class="versions-header">
|
||||||
<h3>New Version</h3>
|
<h3>New Version</h3>
|
||||||
|
|
||||||
<div class="popup-icons">
|
<div class="popup-icons">
|
||||||
<TrashIcon title="Discard Version" @click="deleteVersion" />
|
<button title="Discard Version" @click="deleteVersion">
|
||||||
<SaveIcon title="Save Version" @click="currentVersionIndex = -1" />
|
<TrashIcon />
|
||||||
|
</button>
|
||||||
|
<button title="Exit Version" @click="currentVersionIndex = -1">
|
||||||
|
<ExitIcon />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label
|
<label
|
||||||
@@ -151,7 +160,6 @@
|
|||||||
:allow-empty="false"
|
:allow-empty="false"
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
class="required"
|
|
||||||
title="The version number of this version. Preferably following semantic versioning"
|
title="The version number of this version. Preferably following semantic versioning"
|
||||||
>
|
>
|
||||||
Loaders
|
Loaders
|
||||||
@@ -171,10 +179,7 @@
|
|||||||
:hide-selected="true"
|
:hide-selected="true"
|
||||||
placeholder="Choose loaders..."
|
placeholder="Choose loaders..."
|
||||||
/>
|
/>
|
||||||
<label
|
<label title="The versions of minecraft that this mod version supports">
|
||||||
class="required"
|
|
||||||
title="The versions of minecraft that this mod version supports"
|
|
||||||
>
|
|
||||||
Game Versions
|
Game Versions
|
||||||
</label>
|
</label>
|
||||||
<multiselect
|
<multiselect
|
||||||
@@ -199,7 +204,6 @@
|
|||||||
id="version-body"
|
id="version-body"
|
||||||
v-model="versions[currentVersionIndex].version_body"
|
v-model="versions[currentVersionIndex].version_body"
|
||||||
class="changelog-editor"
|
class="changelog-editor"
|
||||||
placeholder="This editor supports markdown."
|
|
||||||
/>
|
/>
|
||||||
<label class="required" title="The files associated with the version">
|
<label class="required" title="The files associated with the version">
|
||||||
Version Files
|
Version Files
|
||||||
@@ -211,24 +215,35 @@
|
|||||||
multiple
|
multiple
|
||||||
@change="updateVersionFiles"
|
@change="updateVersionFiles"
|
||||||
/>
|
/>
|
||||||
<label for="version-files">Upload files</label>
|
<label for="version-files">{{
|
||||||
|
getFilesSelectedText(
|
||||||
|
versions[currentVersionIndex].file_parts.length,
|
||||||
|
'Upload Files'
|
||||||
|
)
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="versions-header">
|
<div class="versions-header">
|
||||||
<h3>Versions</h3>
|
<h3>Versions</h3>
|
||||||
<PlusIcon @click="createVersion" />
|
<button title="New Version" class="new-version" @click="createVersion">
|
||||||
|
<PlusIcon />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="(value, index) in versions" :key="index" class="version">
|
<div v-for="(value, index) in versions" :key="index" class="version">
|
||||||
<p>{{ value.version_number }}</p>
|
<p>{{ value.version_number }}</p>
|
||||||
<p class="column-grow-4">{{ value.version_title }}</p>
|
<p class="column-grow-4">{{ value.version_title }}</p>
|
||||||
<p>Forge</p>
|
<p>{{ value.loaders.join(', ') }}</p>
|
||||||
<p v-if="value.release_channel === 'beta'" class="badge yellow">Beta</p>
|
<p v-if="value.release_channel === 'beta'" class="badge yellow">Beta</p>
|
||||||
<p v-if="value.release_channel === 'release'" class="badge green">
|
<p v-if="value.release_channel === 'release'" class="badge green">
|
||||||
Release
|
Release
|
||||||
</p>
|
</p>
|
||||||
<p v-if="value.release_channel === 'alpha'" class="badge red">Alpha</p>
|
<p v-if="value.release_channel === 'alpha'" class="badge red">Alpha</p>
|
||||||
<div>
|
<div>
|
||||||
<TrashIcon @click="versions.splice(index, 1)" />
|
<button title="Delete Version" @click="versions.splice(index, 1)">
|
||||||
<EditIcon @click="currentVersionIndex = index" />
|
<TrashIcon />
|
||||||
|
</button>
|
||||||
|
<button title="Edit Version" @click="currentVersionIndex = index">
|
||||||
|
<EditIcon />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -253,7 +268,12 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<button :disabled="!this.$nuxt.$loading" @click="createMod">
|
<button
|
||||||
|
title="Create Mod"
|
||||||
|
class="create-mod"
|
||||||
|
:disabled="!this.$nuxt.$loading"
|
||||||
|
@click="createMod"
|
||||||
|
>
|
||||||
Create mod
|
Create mod
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -266,10 +286,10 @@ import Multiselect from 'vue-multiselect'
|
|||||||
import DOMPurify from 'dompurify'
|
import DOMPurify from 'dompurify'
|
||||||
import marked from 'marked'
|
import marked from 'marked'
|
||||||
|
|
||||||
|
import ExitIcon from '~/assets/images/utils/exit.svg?inline'
|
||||||
import TrashIcon from '~/assets/images/utils/trash.svg?inline'
|
import TrashIcon from '~/assets/images/utils/trash.svg?inline'
|
||||||
import EditIcon from '~/assets/images/utils/edit.svg?inline'
|
import EditIcon from '~/assets/images/utils/edit.svg?inline'
|
||||||
import PlusIcon from '~/assets/images/utils/plus.svg?inline'
|
import PlusIcon from '~/assets/images/utils/plus.svg?inline'
|
||||||
import SaveIcon from '~/assets/images/utils/save.svg?inline'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -277,7 +297,7 @@ export default {
|
|||||||
TrashIcon,
|
TrashIcon,
|
||||||
EditIcon,
|
EditIcon,
|
||||||
PlusIcon,
|
PlusIcon,
|
||||||
SaveIcon,
|
ExitIcon,
|
||||||
},
|
},
|
||||||
async asyncData() {
|
async asyncData() {
|
||||||
let res = await axios.get(`https://api.modrinth.com/api/v1/tag/category`)
|
let res = await axios.get(`https://api.modrinth.com/api/v1/tag/category`)
|
||||||
@@ -347,16 +367,17 @@ export default {
|
|||||||
formData.append('icon', new Blob([this.icon]), this.icon.name)
|
formData.append('icon', new Blob([this.icon]), this.icon.name)
|
||||||
|
|
||||||
for (const version of this.versions) {
|
for (const version of this.versions) {
|
||||||
for (let i = 0; i < version.file_parts; i++) {
|
for (let i = 0; i < version.raw_files.length; i++) {
|
||||||
formData.append(
|
formData.append(
|
||||||
version.file_parts[i],
|
version.file_parts[i],
|
||||||
new Blob([version.raw_files[i]])
|
new Blob([version.raw_files[i]]),
|
||||||
|
version.raw_files[i].name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await axios({
|
await axios({
|
||||||
url: 'https://api.modrinth.com/api/v1/mod',
|
url: 'https://api.modrinth.com/api/v1/mod',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: formData,
|
data: formData,
|
||||||
@@ -367,14 +388,12 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await this.$router.replace('/dashboard/projects')
|
await this.$router.replace('/dashboard/projects')
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.currentError = err.response.data.description
|
this.currentError = err.response.data.description
|
||||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||||
this.$nuxt.$loading.stop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$nuxt.$loading.stop()
|
this.$nuxt.$loading.finish()
|
||||||
},
|
},
|
||||||
showPreviewImage(e) {
|
showPreviewImage(e) {
|
||||||
const reader = new FileReader()
|
const reader = new FileReader()
|
||||||
@@ -389,15 +408,8 @@ export default {
|
|||||||
this.versions[this.currentVersionIndex].raw_files = e.target.files
|
this.versions[this.currentVersionIndex].raw_files = e.target.files
|
||||||
|
|
||||||
const newFileParts = []
|
const newFileParts = []
|
||||||
for (const rawFile of e.target.files) {
|
for (let i = 0; i < e.target.files.length; i++) {
|
||||||
newFileParts.push(
|
newFileParts.push(e.target.files[i].name.concat('-' + i))
|
||||||
rawFile.name.concat(
|
|
||||||
Math.random()
|
|
||||||
.toString(36)
|
|
||||||
.replace(/[^a-z]+/g, '')
|
|
||||||
.substr(0, 5)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.versions[this.currentVersionIndex].file_parts = newFileParts
|
this.versions[this.currentVersionIndex].file_parts = newFileParts
|
||||||
@@ -424,6 +436,15 @@ export default {
|
|||||||
setMarkdownBody() {
|
setMarkdownBody() {
|
||||||
this.compiledBody = DOMPurify.sanitize(marked(this.body))
|
this.compiledBody = DOMPurify.sanitize(marked(this.body))
|
||||||
},
|
},
|
||||||
|
getFilesSelectedText(length, defaultText) {
|
||||||
|
if (length === 0) {
|
||||||
|
return defaultText
|
||||||
|
} else if (length === 1) {
|
||||||
|
return '1 file selected'
|
||||||
|
} else if (length > 1) {
|
||||||
|
return length + ' files selected'
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
head() {
|
head() {
|
||||||
return {
|
return {
|
||||||
@@ -453,7 +474,7 @@ section {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
width: 100%;
|
width: calc(100% - 15px);
|
||||||
padding: 0.5rem 5px;
|
padding: 0.5rem 5px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
@@ -473,6 +494,7 @@ input {
|
|||||||
width: 1px;
|
width: 1px;
|
||||||
|
|
||||||
+ label {
|
+ label {
|
||||||
|
cursor: pointer;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
color: var(--color-grey-5);
|
color: var(--color-grey-5);
|
||||||
background-color: var(--color-grey-1);
|
background-color: var(--color-grey-1);
|
||||||
@@ -549,21 +571,16 @@ input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
.create-mod {
|
||||||
float: right;
|
float: right;
|
||||||
margin: -10px 25px 20px 0;
|
margin: -10px 25px 20px 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
outline: none;
|
outline: none;
|
||||||
color: var(--color-grey-5);
|
color: #fff;
|
||||||
background-color: var(--color-grey-1);
|
background-color: var(--color-brand);
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--color-grey-2);
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.extras {
|
.extras {
|
||||||
@@ -582,9 +599,11 @@ button {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: var(--color-grey-0);
|
background-color: var(--color-grey-3);
|
||||||
|
border: none;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.create-version-popup-body {
|
.create-version-popup-body {
|
||||||
@@ -618,6 +637,10 @@ button {
|
|||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: var(--color-bg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.versions-header {
|
.versions-header {
|
||||||
@@ -651,9 +674,11 @@ button {
|
|||||||
background-color: var(--color-grey-1);
|
background-color: var(--color-grey-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
button {
|
||||||
|
background-color: var(--color-grey-1);
|
||||||
color: var(--color-grey-5);
|
color: var(--color-grey-5);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@@ -666,6 +691,6 @@ svg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.no-scroll {
|
.no-scroll {
|
||||||
overflow: hidden;
|
overflow: hidden !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<h2>Mods</h2>
|
<h2>Mods</h2>
|
||||||
<section class="search-bar">
|
<section class="search-bar">
|
||||||
<div class="iconified-input column-grow-2">
|
<div class="iconified-input column-grow-2">
|
||||||
|
<label class="hidden" for="search">Search Mods</label>
|
||||||
<input
|
<input
|
||||||
id="search"
|
id="search"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
@@ -95,7 +96,6 @@
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<section id="filters" class="filters">
|
<section id="filters" class="filters">
|
||||||
<!--#region filters -->
|
|
||||||
<div class="filters-wrapper">
|
<div class="filters-wrapper">
|
||||||
<section class="filter-group">
|
<section class="filter-group">
|
||||||
<button class="filter-button-done" @click="toggleFiltersMenu">
|
<button class="filter-button-done" @click="toggleFiltersMenu">
|
||||||
@@ -247,7 +247,6 @@
|
|||||||
@input="onSearchChange(1)"
|
@input="onSearchChange(1)"
|
||||||
></multiselect>
|
></multiselect>
|
||||||
</div>
|
</div>
|
||||||
<!--#endregion -->
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -684,6 +683,11 @@ select {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.multiselect__tags {
|
||||||
|
border: 2px solid var(--color-grey-3);
|
||||||
|
border-radius: var(--size-rounded-sm);
|
||||||
|
}
|
||||||
|
|
||||||
.multiselect__tags,
|
.multiselect__tags,
|
||||||
.multiselect__spinner {
|
.multiselect__spinner {
|
||||||
background: var(--color-bg);
|
background: var(--color-bg);
|
||||||
|
|||||||
@@ -1,7 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="content">
|
||||||
<img :src="user.avatar_url" />
|
<div class="user-profile">
|
||||||
<div>
|
<img :src="user.avatar_url" :alt="user.username" />
|
||||||
|
<div class="info">
|
||||||
|
<h1>{{ user.username }}</h1>
|
||||||
|
<p>{{ user.bio }}</p>
|
||||||
|
<p>Joined {{ $dayjs(user.created).fromNow() }}</p>
|
||||||
|
<p></p>
|
||||||
|
<p v-if="user.role === 'admin'" class="badge red">Admin</p>
|
||||||
|
<p v-if="user.role === 'moderator'" class="badge yellow">Moderator</p>
|
||||||
|
<p v-if="user.role === 'developer'" class="badge green">Developer</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="user-mods">
|
||||||
<SearchResult
|
<SearchResult
|
||||||
v-for="(result, index) in mods"
|
v-for="(result, index) in mods"
|
||||||
:id="result.mod_id"
|
:id="result.mod_id"
|
||||||
@@ -56,4 +67,40 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss"></style>
|
<style lang="scss" scoped>
|
||||||
|
.user-profile {
|
||||||
|
@media screen and (min-width: 900px) {
|
||||||
|
display: inline-flex;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 15px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 250px;
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
margin-left: 15px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-mods {
|
||||||
|
border-top: 1px solid var(--color-grey-1);
|
||||||
|
padding-top: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
* {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user