[WIP] Rework design (#34)

* WIP: Redesign the default layout

* Merge old & new default layouts

* Fix login logic; add proper user controls dropdown

* Fix latest version listing (#31) (#32)

Co-authored-by: Aeledfyr <45501007+Aeledfyr@users.noreply.github.com>

* First pass of design cleanup

* Improve ad integration and fix light theme

* Begin splitting up variables, change some styling to new mockup

* Continue redesign progress

* Work on some more pages

* Add missing dark theme variables for text

* Continue working on modularizing

* Continue progress, redo pagination

* Fix auth buttons in navbar layout

* Continue progress

* Continue progress more

* Redo ModResult

* Scope ModPage :irritater:

* Continue Dashboard

* Continue progress on Dashboard and cleanup

* Add missing variables for dark theme

* Small tweaks, cleanup, and continue mod page progress

* Fix user not being able to see hidden mods that they own

* Start reworking mod creation

* Continue revamp of mod creation page

* Yank v-html out

* Hotfix markdown rendering and some spacing issues

* Move legal; continue with mod creation; create reusable footer

* Create README.md

* Update README.md

* Update README.md

* Add in basic usage instructions

* Fix some stuff

* Continue with mod creation; fix some CSS errors

* Start user page

* Start transition to vue-select; fix a few bugs

* Continue mod creation page

* Finish mod pages

* Add very raw version editing

* Mod editing + creation

* Fixed versions that were in processing causing a 404 (#39)

Co-authored-by: Mikhail Oleynikov <falseresync@gmail.com>
Co-authored-by: Aeledfyr <45501007+Aeledfyr@users.noreply.github.com>
Co-authored-by: Jai A <jai.a@tuta.io>
Co-authored-by: MulverineX <mulverin3@gmail.com>
Co-authored-by: diabolical17 <calumproh28@gmail.com>
Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
Prospector
2020-11-30 13:55:01 -08:00
committed by GitHub
parent e025df0824
commit 7b84d8c3d5
70 changed files with 10339 additions and 3284 deletions
+217 -190
View File
@@ -1,109 +1,115 @@
<template>
<ModPage :mod="mod" :versions="versions" :members="members">
<div class="version">
<div class="header">
<h3>{{ version.name }}</h3>
<div
v-if="
this.$auth.loggedIn &&
members.find((x) => x.user_id === this.$auth.user.id)
<div class="version-header">
<h4>{{ version.name }}</h4>
<span v-if="version.version_type === 'release'" class="badge green">
Release
</span>
<span v-if="version.version_type === 'beta'" class="badge yellow">
Beta
</span>
<span v-if="version.version_type === 'alpha'" class="badge red">
Alpha
</span>
<span>
{{ version.version_number }}
</span>
<Categories :categories="version.loaders" />
<a
:href="primaryFile.url"
class="download-button"
@click.prevent="
downloadFile(primaryFile.hashes.sha1, primaryFile.url)
"
class="user-actions"
>
<button class="trash red">
<TrashIcon />
</button>
<button class="upload" @click="showPopup = !showPopup">
<UploadIcon />
</button>
<DownloadIcon />
Download
</a>
</div>
<div class="stats">
<div class="stat">
<DownloadIcon />
<div class="info">
<h4>Downloads</h4>
<p class="value">{{ version.downloads }}</p>
</div>
</div>
<div class="stat">
<CalendarIcon />
<div class="info">
<h4>Created</h4>
<p
v-tooltip="
$dayjs(version.published).format(
'[Created on] YYYY-MM-DD [at] HH:mm A'
)
"
class="value"
>
{{ $dayjs(version.published).fromNow() }}
</p>
</div>
</div>
<div class="stat">
<TagIcon />
<div class="info">
<h4>Available For</h4>
<p class="value">
{{ version.game_versions.join(', ') }}
</p>
</div>
</div>
</div>
<div class="markdown-body" v-html="changelog"></div>
<hr />
<div class="columns metadata">
<div class="author">
<img :src="version.author.avatar_url" />
<p>{{ version.author.name }}</p>
</div>
<p>{{ version.downloads }} Downloads</p>
<div>
<FabricIcon
v-if="version.loaders.includes('fabric')"
stroke="#AC6C3A"
/>
<ForgeIcon
v-if="version.loaders.includes('forge')"
stroke="#8B81E6"
/>
</div>
<div class="game-versions">
<p v-for="gameVersion in version.game_versions" :key="gameVersion">
{{ gameVersion }}
</p>
</div>
</div>
<hr />
<div v-compiled-markdown="changelog" class="markdown-body"></div>
<div class="files">
<div v-for="file in version.files" :key="file.hashes.sha1">
<p>{{ file.filename }}</p>
<a :href="file.url" download>
<div class="text-wrapper">
<p>{{ file.filename }}</p>
<div
v-if="
$auth.loggedIn &&
members.find((x) => x.user_id === $auth.user.id)
"
class="actions"
>
<button @click="deleteFile(file.hashes.sha1)">Delete File</button>
<button @click="makePrimary(file.hashes.sha1)">
Make Primary
</button>
</div>
</div>
<a
:href="file.url"
@click.prevent="downloadFile(file.hash, file.url)"
>
<DownloadIcon />
</a>
</div>
</div>
<FileInput class="file-input" @change="addFiles" />
</div>
<Popup :show-popup="showPopup">
<h3 class="popup-title">Upload Files</h3>
<FileInput
input-id="version-files"
input-accept="application/*"
default-text="Upload Files"
:input-multiple="true"
@change="addFiles"
>
<label class="required" title="The files associated with the version">
Version Files
</label>
</FileInput>
<div class="popup-buttons">
<button
class="trash-button"
@click="
showPopup = false
filesToUpload = []
"
>
<TrashIcon />
</button>
<button class="default-button" @click="uploadFiles">Upload</button>
</div>
</Popup>
</ModPage>
</template>
<script>
import axios from 'axios'
import ModPage from '@/components/ModPage'
import xss from 'xss'
import marked from 'marked'
import Popup from '@/components/Popup'
import Categories from '@/components/Categories'
import FileInput from '@/components/FileInput'
import DownloadIcon from '~/assets/images/utils/download.svg?inline'
import UploadIcon from '~/assets/images/utils/upload.svg?inline'
import TrashIcon from '~/assets/images/utils/trash.svg?inline'
import ForgeIcon from '~/assets/images/categories/forge.svg?inline'
import FabricIcon from '~/assets/images/categories/fabric.svg?inline'
import CalendarIcon from '~/assets/images/utils/calendar.svg?inline'
import TagIcon from '~/assets/images/utils/tag.svg?inline'
export default {
components: {
Popup,
FileInput,
Categories,
ModPage,
ForgeIcon,
FabricIcon,
DownloadIcon,
UploadIcon,
TrashIcon,
CalendarIcon,
TagIcon,
},
auth: false,
async asyncData(data) {
@@ -125,11 +131,15 @@ export default {
const versions = []
for (const version of mod.versions) {
res = await axios.get(
`https://api.modrinth.com/api/v1/version/${version}`
)
versions.push(res.data)
try {
res = await axios.get(
`https://api.modrinth.com/api/v1/version/${version}`
)
versions.push(res.data)
} catch {
// eslint-disable-next-line no-console
console.log('Some versions may be missing...')
}
}
const version = versions.find((x) => x.id === data.params.version)
@@ -138,8 +148,13 @@ export default {
let changelog = ''
if (version.changelog_url) {
res = await axios.get(version.changelog_url)
changelog = xss(marked(res.data))
changelog = (await axios.get(version.changelog_url)).data
}
let primaryFile = version.files.find((file) => file.primary)
if (!primaryFile) {
primaryFile = version.files[0]
}
return {
@@ -148,16 +163,55 @@ export default {
members,
version,
changelog,
primaryFile,
}
},
data() {
return {
showPopup: false,
filesToUpload: [],
}
},
methods: {
addFiles(e) {
async downloadFile(hash, url) {
await axios.get(
`https://api.modrinth.com/api/v1/version_file/${hash}/download`
)
const elem = document.createElement('a')
elem.download = hash
elem.href = url
elem.click()
},
async deleteFile(hash) {
const config = {
headers: {
Authorization: this.$auth.getToken('local'),
},
}
await axios.delete(
`https://api.modrinth.com/api/v1/version_file/${hash}`,
config
)
},
async makePrimary(hash) {
const config = {
headers: {
Authorization: this.$auth.getToken('local'),
},
}
await axios.patch(
`https://api.modrinth.com/api/v1/version/${this.version.id}`,
{
primary_file: {
sha1: hash,
},
},
config
)
},
async addFiles(e) {
this.filesToUpload = e.target.files
for (let i = 0; i < e.target.files.length; i++) {
@@ -165,8 +219,7 @@ export default {
'-' + i
)
}
},
async uploadFiles() {
this.$nuxt.$loading.start()
const formData = new FormData()
@@ -254,70 +307,38 @@ export default {
<style lang="scss" scoped>
.version {
background: var(--color-bg);
border-radius: 0 0 0.5rem 0.5rem;
box-shadow: 0 2px 3px 1px var(--color-grey-2);
padding: 1em;
margin-bottom: var(--spacing-card-md);
background: var(--color-raised-bg);
border-radius: var(--size-rounded-card);
padding: 1rem;
.header {
h3 {
display: inline-block;
}
.user-actions {
float: right;
button {
cursor: pointer;
margin-right: 10px;
padding: 5px;
border: none;
border-radius: var(--size-rounded-sm);
}
.trash {
color: #9b2c2c;
background-color: var(--color-bg);
}
.upload {
color: var(--color-text);
background-color: var(--color-grey-1);
* {
margin: auto 0;
}
}
}
}
hr {
margin: 20px 0;
color: var(--color-grey-1);
}
.metadata {
.version-header {
display: flex;
align-items: center;
justify-content: space-between;
.author {
h4,
span {
margin: auto 0.5rem auto 0;
}
.download-button {
margin-left: auto;
padding: 0.5rem;
color: var(--color-button-text);
background-color: var(--color-button-bg);
justify-self: flex-end;
display: flex;
align-items: center;
img {
height: 50px;
width: 50px;
margin-right: 10px;
}
}
}
border-radius: var(--size-rounded-sm);
.game-versions {
max-width: 200px;
p {
margin: 0 0 0 10px;
padding: 4px;
font-size: 15px;
color: var(--color-text);
background-color: var(--color-grey-1);
display: inline-block;
&:hover,
&:focus {
background-color: var(--color-button-bg-hover);
}
svg {
margin-right: 0.25rem;
}
}
}
@@ -326,71 +347,77 @@ export default {
div {
display: flex;
margin-right: 10px;
border: 1px solid var(--color-grey-1);
border-radius: var(--size-rounded-sm);
margin-right: 0.5rem;
background: var(--color-bg);
border-radius: var(--size-rounded-control);
p {
margin-left: 10px;
margin-right: 10px;
.text-wrapper {
display: flex;
flex-direction: column;
padding: 0.5rem;
.actions {
width: 100%;
display: flex;
justify-content: space-between;
max-height: 3rem;
font-size: var(--font-size-sm);
button {
display: flex;
align-items: center;
svg {
margin-left: 0.25rem;
}
}
}
}
a {
display: table-cell;
display: flex;
align-items: center;
margin-left: auto;
width: 40px;
height: 60px;
background-color: var(--color-grey-1);
color: var(--color-grey-3);
width: 2.5rem;
height: auto;
background-color: var(--color-button-bg);
color: var(--color-button-text);
border-radius: 0 var(--size-rounded-control) var(--size-rounded-control)
0;
svg {
margin-top: 15px;
vertical-align: center;
height: 30px;
width: 40px;
}
&:hover,
&:focus {
background-color: var(--color-grey-3);
color: var(--color-grey-4);
background-color: var(--color-button-bg-hover);
color: var(--color-button-text-hover);
}
}
}
}
}
.popup-title {
margin-bottom: 40px;
}
.popup-buttons {
margin-top: 40px;
.stats {
display: flex;
justify-content: left;
align-items: center;
flex-wrap: wrap;
margin: 0.5rem 0;
.stat {
margin-right: 0.75rem;
@extend %stat;
.default-button {
border-radius: var(--size-rounded-sm);
cursor: pointer;
border: none;
padding: 10px;
background-color: var(--color-grey-1);
color: var(--color-grey-5);
&:hover,
&:focus {
color: var(--color-grey-4);
svg {
padding: 0.25rem;
border-radius: 50%;
background-color: var(--color-button-bg);
}
}
}
.trash-button {
cursor: pointer;
margin-right: 10px;
padding: 5px;
border: none;
border-radius: var(--size-rounded-sm);
color: #9b2c2c;
background-color: var(--color-bg);
}
.file-input {
margin-top: 2rem;
}
</style>