Skip to content

Commit

Permalink
merge all dynamic icons into single component
Browse files Browse the repository at this point in the history
  • Loading branch information
3vorp committed Dec 23, 2024
1 parent c033da3 commit 7dfc140
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 111 deletions.
31 changes: 8 additions & 23 deletions _includes/article_download.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,17 @@ <h2 class="subtitle my-5 text-center">Downloads</h2>
<div id="download"></div>
<script>
// todo: merge this with the vue post download component
function handleIcon(downloadName) {
const name = downloadName.toLowerCase().trim();
if (name.includes("github")) return ["fab", ""];
if (name.includes("curseforge")) return ["fas", ""];
if (["planetminecraft", "pmc", "planet minecraft"].some((search) => name.includes(search)))
return ["fas", ""];
if (name.includes("mcpedl")) return ["fas", ""];
if (name.includes("modrinth")) return ["fas", ""];
// default download icon
return ["fas", ""];
}

function formatDownloads(downloadObj) {
// liquid iteration sucks so I switched it to plain JS
const items = Object.entries(downloadObj).map(([category, items]) => {
const downloadList = Object.entries(items).map(([name, link]) => {
const [className, icon] = handleIcon(name);
return `
<p class="text-center">
<a href="${link}" class="btn block btn-lg btn-primary">
<i style="margin-right: 10px" class="${className}">${icon}</i>
${name}
</a>
</p>
`;
});
const downloadList = Object.entries(items).map(
([name, link]) =>
`<a href="${link}" class="btn block btn-lg btn-primary">
<i class="fas"></i>
<span style="margin-left: 8px">${name}</span>
</a>
`,
);
return `
<h1 class="my-3 text-center">${category}</h1>
${downloadList.join("")}
Expand Down
14 changes: 5 additions & 9 deletions css/downloads.scss
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ td {

.link-text {
padding: 0;
margin-left: 8px;
}

.mobile-details {
Expand All @@ -121,9 +122,8 @@ td {
width: 110px;
}

.btn-dl > i {
i.dl-icon {
font-size: small;
margin-right: 8px;
}

// mobile layout
Expand Down Expand Up @@ -188,13 +188,9 @@ td {
line-height: 30px;
text-align: center;
padding: 0;

i {
display: block;
height: 30px;
line-height: 30px;
margin-right: 0 !important;
}
display: flex;
align-items: center;
justify-content: center;
}

.link-text {
Expand Down
1 change: 1 addition & 0 deletions css/lib/buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ a.btn.disabled {
font-size: 1.25rem;
line-height: 1.5;
border-radius: 0.3rem;
margin-bottom: 1rem;
}

.btn-lang {
Expand Down
4 changes: 4 additions & 0 deletions css/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ button:not(:disabled),
.fab, .fas {
font-style: normal;
}
.custom-icon {
width: 1.25em;
height: 1.25em;
}
.title {
font-size: 4.8rem;
line-height: 1.2;
Expand Down
42 changes: 6 additions & 36 deletions js/addon/author-media.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export default {
name: "author-media",
components: {
MediaIcon: Vue.defineAsyncComponent(() => import("../components/media-icon.js")),
},
props: {
media: {
type: Object,
Expand All @@ -8,46 +11,13 @@ export default {
},
template: `
<a class="author-media" :href="formattedURL" target="_blank" rel="noreferrer">
<img
v-if="MEDIAS_TO_ICONS[media.type].type === 'image'"
width="24"
height="24"
:src="MEDIAS_TO_ICONS[media.type].data"
:alt="media.type"
/>
<i
v-else
:class="MEDIAS_TO_ICONS[media.type || 'Other'].type || 'fas'"
>
{{ MEDIAS_TO_ICONS[media.type || "Other"].data || MEDIAS_TO_ICONS["Other"] }}
</i>
<media-icon :icon="media.type" />
</a>
`,
data() {
return {
MEDIAS_TO_ICONS: {
CurseForge: { type: "image", data: "/image/icons/curseforge.svg" },
GitHub: { type: "fab", data: "" },
Modrinth: { type: "fas", data: "" },
Patreon: { type: "fab", data: "" },
Paypal: { type: "fab", data: "" },
"Planet Minecraft": { type: "fas", data: "" },
PSN: { type: "fab", data: "" },
Reddit: { type: "fab", data: "" },
Steam: { type: "fab", data: "" },
Twitter: { type: "fab", data: "" },
Website: { type: "fas", data: "" },
Xbox: { type: "fab", data: "" },
YouTube: { type: "fab", data: "" },
Other: { type: "fas", data: "" },
},
};
},
computed: {
formattedURL() {
return !/^https?:\/\//i.test(this.media.link)
? `http://${this.media.link}`
: this.media.link;
const url = this.media.link;
return !/^https?:\/\//i.test(url) ? `http://${url}` : url;
},
},
};
11 changes: 8 additions & 3 deletions js/addon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,14 @@ document.addEventListener("DOMContentLoaded", () => {
<h2 id="downloads" class="subtitle text-center" style="margin-bottom:3rem;margin-top:2rem;">
Downloads
</h2>
<p v-for="file in downloads" :key="file.source" class="text-center">
<a class="btn block btn-lg btn-primary" :href="file.source">{{ file.name }}</a>
</p>
<a
v-for="file in downloads"
:key="file.source"
:href="file.source"
class="btn block btn-lg btn-primary"
>
{{ file.name }}
</a>
<br /><br />
<discord-button />
</div>
Expand Down
65 changes: 65 additions & 0 deletions js/components/media-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// handles all weird custom icon behavior and edge cases
export default {
name: "media-icon",
props: {
icon: {
type: String,
required: true,
},
fallback: {
type: String,
required: false,
default: "other",
},
},
template: `
<img v-if="isImage" class="custom-icon" :src="iconData" :alt="cleanedIcon" />
<i v-else :class="iconType">{{ iconData }}</i>
`,
data() {
return {
icons: {
// expand this list as needed
download: { data: "", type: "fas" },
curseforge: { data: "/image/icons/curseforge.svg", type: "image" },
github: { data: "", type: "fab" },
modrinth: { data: "", type: "fas" },
mcpedl: { data: "", type: "fas" },
patreon: { type: "fab", data: "" },
paypal: { type: "fab", data: "" },
pmc: { type: "fas", data: "" },
psn: { type: "fab", data: "" },
reddit: { type: "fab", data: "" },
steam: { type: "fab", data: "" },
twitter: { type: "fab", data: "" },
website: { type: "fas", data: "" },
xbox: { type: "fab", data: "" },
youtube: { type: "fab", data: "" },
other: { type: "fas", data: "" },
},
};
},
computed: {
cleanedIcon() {
const cleaned = this.icon.toLowerCase().trim();
// fix exceptions, expand if needed
switch (cleaned) {
case "curse":
return "curseforge";
case "planet minecraft":
case "planetminecraft":
return "pmc";
}
return cleaned || this.fallback;
},
iconType() {
return this.icons[this.cleanedIcon]?.type;
},
iconData() {
return this.icons[this.cleanedIcon]?.data;
},
isImage() {
return this.iconType === "image";
},
},
};
19 changes: 11 additions & 8 deletions js/download/download-line.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export default {
name: "download-line",
components: {
MediaIcon: Vue.defineAsyncComponent(() => import("../components/media-icon.js")),
},
props: {
nested: {
type: Boolean,
Expand Down Expand Up @@ -53,21 +56,21 @@ export default {
:colspan="Object.keys(item.links).length > 1 ? 1 : 2"
>
<a class="btn btn-dark btn-dl" :href="link">
<i :class="buttonData[linkType]?.type || 'fas'">{{ buttonData[linkType]?.icon || "" }}</i>
<span class="link-text">{{ buttonData[linkType]?.text || linkType }}</span>
<media-icon class="dl-icon" :icon="linkType" />
<span class="link-text">{{ textFormat[linkType] || linkType }}</span>
</a>
</td>
</tr>
`,
data() {
return {
isOpen: false,
buttonData: {
download: { icon: "", text: "Download", type: "fas" },
curse: { icon: "", text: "Curse", type: "fas" },
github: { icon: "", text: "GitHub", type: "fab" },
modrinth: { icon: "", text: "Modrinth", type: "fas" },
mcpedl: { icon: "", text: "MCPEDL", type: "fas" },
textFormat: {
download: "Download",
curse: "Curse",
github: "GitHub",
modrinth: "Modrinth",
mcpedl: "MCPEDL",
},
labelColors: {
GitHub: "github",
Expand Down
2 changes: 1 addition & 1 deletion js/mods/components/mods/download-minecraft-version.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default {
<span :style="{display: block ? 'block' : 'initial' }">
{{ value.version }}
</span>
<span class="badge badge-light" style="color: black">
<span class="badge badge-light" style="color: black; margin-left: 5px">
{{ value.count }}
</span>
</button>
Expand Down
46 changes: 15 additions & 31 deletions js/posts/post-downloads.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export default {
name: "post-downloads",
components: {
MediaIcon: Vue.defineAsyncComponent(() => import("../components/media-icon.js")),
},
props: {
downloads: {
type: Object,
Expand All @@ -10,45 +13,26 @@ export default {
<h2 class="subtitle my-5 text-center">Downloads</h2>
<template v-for="[category, items] in Object.entries(downloads)">
<a
v-if="isSingleDownload(items)"
v-if="typeof items === 'string'"
:href="items"
class="btn block btn-lg btn-primary my-3"
>
<i style="margin-right: 10px" :class="getIcon(items).cls">
{{ getIcon(items).icon }}
</i>{{ category }}
<media-icon :icon="items" />
<span style="margin-left: 8px">{{ category }}</span>
</a>
<template v-else>
<h1 class="my-3 text-center">{{ category }}</h1>
<p v-for="[name, link] in Object.entries(items)" class="text-center">
<a :href="link" class="btn block btn-lg btn-primary">
<i style="margin-right: 10px" :class="getIcon(name).cls">
{{ getIcon(name).icon }}
</i>{{ name }}
</a>
</p>
<a
v-for="[name, link] in Object.entries(items)"
:key="link"
:href="link"
class="btn block btn-lg btn-primary"
>
<media-icon :icon="name" />
<span style="margin-left: 8px">{{ name }}</span>
</a>
<br />
</template>
</template>
`,
methods: {
isSingleDownload(item) {
return typeof item === "string";
},
getIcon(item) {
const name = item.toLowerCase().trim();
if (name.includes("github")) return { cls: "fab", icon: "" };
if (name.includes("curseforge")) return { cls: "fas", icon: "" };
if (
["planetminecraft", "pmc", "planet minecraft"].some((search) =>
name.includes(search),
)
)
return { cls: "fas", icon: "" };
if (name.includes("mcpedl")) return { cls: "fas", icon: "" };
if (name.includes("modrinth")) return { cls: "fas", icon: "" };
// default download icon
return { cls: "fas", icon: "" };
},
},
};

0 comments on commit 7dfc140

Please sign in to comment.