UI/UX improvements (#146)

* Some initial changes

* New project cards

* Version

* Finalize improvements

* Fixed styling issues on versions page

* Removed light mode

* Run linter

* Added mixpanel stuff in context menus

* Fix styling issues

* Fix windows

* homepage fixes

* Finishing touches on mac styling

* Fixed windows related styling

* Update global.scss

---------

Co-authored-by: Jai A <jaiagr+gpg@pm.me>
This commit is contained in:
Adrian O.V
2023-06-20 00:09:03 -04:00
committed by GitHub
parent 1e78a7b6a8
commit bd697a02f5
25 changed files with 985 additions and 491 deletions

View File

@@ -57,21 +57,22 @@
Folder
</Button>
</span>
<hr class="card-divider" />
<div class="pages-list">
<RouterLink :to="`/instance/${encodeURIComponent($route.params.id)}/`" class="btn">
<BoxIcon />
Mods
</RouterLink>
<RouterLink :to="`/instance/${encodeURIComponent($route.params.id)}/logs`" class="btn">
<FileIcon />
Logs
</RouterLink>
<RouterLink :to="`/instance/${encodeURIComponent($route.params.id)}/options`" class="btn">
<SettingsIcon />
Options
</RouterLink>
</div>
</Card>
<div class="pages-list">
<RouterLink :to="`/instance/${encodeURIComponent($route.params.id)}/`" class="btn">
<BoxIcon />
Mods
</RouterLink>
<RouterLink :to="`/instance/${encodeURIComponent($route.params.id)}/logs`" class="btn">
<FileIcon />
Logs
</RouterLink>
<RouterLink :to="`/instance/${encodeURIComponent($route.params.id)}/options`" class="btn">
<SettingsIcon />
Options
</RouterLink>
</div>
</div>
<div class="content">
<Promotion />
@@ -266,7 +267,6 @@ onUnmounted(() => {
<style scoped lang="scss">
.instance-card {
background: var(--color-bg);
display: flex;
flex-direction: column;
gap: 1rem;
@@ -288,7 +288,6 @@ Button {
display: flex;
flex-direction: column;
padding: 1rem;
background: var(--color-raised-bg);
min-height: calc(100% - 3.25rem);
overflow: hidden;
}
@@ -321,7 +320,7 @@ Button {
}
.content {
margin-left: 20rem;
margin-left: 19rem;
}
.instance-info {
@@ -341,7 +340,7 @@ Button {
.pages-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
gap: var(--gap-xs);
a {
font-size: 100%;
@@ -350,7 +349,6 @@ Button {
transition: all ease-in-out 0.1s;
width: 100%;
color: var(--color-primary);
padding: var(--gap-md);
box-shadow: none;
&.router-link-exact-active {
@@ -373,28 +371,6 @@ Button {
}
}
.header-nav {
height: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 0.5rem;
gap: 0.5rem;
background: var(--color-raised-bg);
}
.project-card {
height: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 1rem;
background: var(--color-raised-bg);
width: 20rem;
}
.instance-nav {
display: flex;
flex-direction: row;
@@ -402,7 +378,6 @@ Button {
justify-content: left;
padding: 1rem;
gap: 0.5rem;
background: var(--color-raised-bg);
height: min-content;
width: 100%;
}

View File

@@ -52,17 +52,28 @@
v-model="selectedProjectType"
:items="Object.keys(selectableProjectTypes)"
/>
<Button :disabled="!projects.some((x) => x.outdated)" class="no-wrap" @click="updateAll">
<UpdatedIcon />
Update {{ selected.length > 0 ? 'selected' : 'all' }}
</Button>
<DropdownButton
:options="['update_all', 'filter_update']"
default-value="update_all"
:disabled="!projects.some((x) => x.outdated)"
@option-click="updateAll"
>
<template #update_all>
<UpdatedIcon />
Update {{ selected.length > 0 ? 'selected' : 'all' }}
</template>
<template #filter_update>
<UpdatedIcon />
Select Updatable
</template>
</DropdownButton>
<Button v-if="selected.length > 0" class="no-wrap" @click="deleteWarning.show()">
<TrashIcon />
Remove selected
</Button>
<DropdownButton
v-if="selected.length > 0"
:options="['toggle', 'disable', 'enable']"
:options="['toggle', 'disable', 'enable', 'hide_show']"
default-value="toggle"
@option-click="toggleSelected"
>
@@ -78,6 +89,10 @@
<CheckCircleIcon />
Enable selected
</template>
<template #hide_show>
<CheckCircleIcon />
{{ hideNonSelected ? 'Show' : 'Hide' }} unselected
</template>
</DropdownButton>
<DropdownButton
v-if="selected.length > 0"
@@ -299,6 +314,7 @@ const sortFilter = ref('')
const selectedProjectType = ref('All')
const selected = computed(() => projects.value.filter((mod) => mod.selected))
const deleteWarning = ref(null)
const hideNonSelected = ref(false)
const selectableProjectTypes = computed(() => {
const obj = { All: 'all' }
@@ -313,12 +329,19 @@ const selectableProjectTypes = computed(() => {
const search = computed(() => {
const projectType = selectableProjectTypes.value[selectedProjectType.value]
const filtered = projects.value.filter((mod) => {
return (
mod.name.toLowerCase().includes(searchFilter.value.toLowerCase()) &&
(projectType === 'all' || mod.project_type === projectType)
)
})
const filtered = projects.value
.filter((mod) => {
return (
mod.name.toLowerCase().includes(searchFilter.value.toLowerCase()) &&
(projectType === 'all' || mod.project_type === projectType)
)
})
.filter((mod) => {
if (hideNonSelected.value) {
return mod.selected
}
return true
})
return updateSort(filtered, sortFilter.value)
})
@@ -368,37 +391,45 @@ function updateSort(projects, sort) {
}
}
async function updateAll() {
const setProjects = []
for (const [i, project] of selected.value ?? projects.value.entries()) {
if (project.outdated) {
project.updating = true
setProjects.push(i)
async function updateAll(args) {
if (args.option === 'update_all') {
const setProjects = []
for (const [i, project] of selected.value ?? projects.value.entries()) {
if (project.outdated) {
project.updating = true
setProjects.push(i)
}
}
const paths = await update_all(props.instance.path).catch(handleError)
for (const [oldVal, newVal] of Object.entries(paths)) {
const index = projects.value.findIndex((x) => x.path === oldVal)
projects.value[index].path = newVal
projects.value[index].outdated = false
if (projects.value[index].updateVersion) {
projects.value[index].version = projects.value[index].updateVersion.version_number
projects.value[index].updateVersion = null
}
}
for (const project of setProjects) {
projects.value[project].updating = false
}
mixpanel.track('InstanceUpdateAll', {
loader: props.instance.metadata.loader,
game_version: props.instance.metadata.game_version,
count: setProjects.length,
selected: selected.value.length > 1,
})
} else {
for (const project of projects.value) {
if (project.outdated) {
project.selected = true
}
}
}
const paths = await update_all(props.instance.path).catch(handleError)
for (const [oldVal, newVal] of Object.entries(paths)) {
const index = projects.value.findIndex((x) => x.path === oldVal)
projects.value[index].path = newVal
projects.value[index].outdated = false
if (projects.value[index].updateVersion) {
projects.value[index].version = projects.value[index].updateVersion.version_number
projects.value[index].updateVersion = null
}
}
for (const project of setProjects) {
projects.value[project].updating = false
}
mixpanel.track('InstanceUpdateAll', {
loader: props.instance.metadata.loader,
game_version: props.instance.metadata.game_version,
count: setProjects.length,
selected: selected.value.length > 1,
})
}
async function updateProject(mod) {
@@ -523,6 +554,9 @@ async function toggleSelected(args) {
}
}
break
case 'hide_show':
hideNonSelected.value = !hideNonSelected.value
break
}
}