Két tengelyen kap vissza életet a felület: piktogram és szín
A facelift után a site helyenként túl csendes lett. Élet kerül vissza, de nem dekorációként: két szabály mentén, amiket egymástól függetlenül lehet olvasni. A piktogram identitást jelöl — miféle dolog ez. Minden motor és platform saját glifát kap (TIC-80, Ebitengine, LÖVE, Godot, Bevy, Phaser, C64), és ugyanazt a jelet viszi a katalógusban, a részletlapon és a build-mátrix motor-oszlopában, egyetlen PlatformIcon komponensből. A Contact IRC- és BBS-csatornája is jelet kapott, mert a másik három brandnek eddig is volt, és a hiány látszott. A szín állapotot jelöl — mi van vele. A négy státuszból három kap hangot: a megjelent az akcens zöldet, a demó egy kéket (új --c-info token, 6,7:1 fehéren és 7,8:1 feketén), a fejlesztés alatti a borostyánt. Az archivált marad semleges, mert az a "már nem történik vele semmi" állapot. A navigáció, a gombok és a szekciócímek továbbra sem kapnak ikont: ott a szöveg megmondja, mi az. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
<template>
|
||||
<span class="badge">{{ platform }}</span>
|
||||
<span class="badge gap-1.5">
|
||||
<PlatformIcon :platform="platform" />{{ platform }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import PlatformIcon from './PlatformIcon.vue'
|
||||
|
||||
defineProps<{ platform: string }>()
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<BrandIcon v-if="brand" :name="brand" />
|
||||
<component :is="glyph" v-else v-bind="ICON" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, type Component } from 'vue'
|
||||
import { Bot, Box, Boxes, Heart, Save, Tv, Zap } from 'lucide-vue-next'
|
||||
import BrandIcon from './icons/BrandIcon.vue'
|
||||
import { ICON } from './icons'
|
||||
|
||||
const props = defineProps<{ platform: string }>()
|
||||
|
||||
const GLYPHS: Record<string, Component> = {
|
||||
tic80: Tv,
|
||||
love: Heart,
|
||||
godot: Bot,
|
||||
bevy: Boxes,
|
||||
phaser: Zap,
|
||||
c64: Save,
|
||||
}
|
||||
|
||||
const key = computed(() => props.platform.toLowerCase().replace(/[^a-z0-9]/g, ''))
|
||||
const brand = computed(() => (key.value === 'ebitengine' ? 'go' : null))
|
||||
const glyph = computed(() => GLYPHS[key.value] ?? Box)
|
||||
</script>
|
||||
@@ -0,0 +1,27 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import PlatformBadge from '../PlatformBadge.vue'
|
||||
import { statusBadgeClass } from '../../lib/softwareUtils'
|
||||
|
||||
describe('PlatformBadge', () => {
|
||||
it('shows the platform name next to its own glyph', () => {
|
||||
const wrapper = mount(PlatformBadge, { props: { platform: 'TIC-80' } })
|
||||
expect(wrapper.text()).toContain('TIC-80')
|
||||
expect(wrapper.find('svg').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('falls back to a glyph for a platform it has never seen', () => {
|
||||
const wrapper = mount(PlatformBadge, { props: { platform: 'Amiga' } })
|
||||
expect(wrapper.find('svg').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('statusBadgeClass', () => {
|
||||
it('gives every live status its own hue and leaves the archived ones neutral', () => {
|
||||
expect(statusBadgeClass('released')).toContain('status-released')
|
||||
expect(statusBadgeClass('demo')).toContain('status-demo')
|
||||
expect(statusBadgeClass('development')).toContain('status-development')
|
||||
expect(statusBadgeClass('archived')).toBe('status-badge')
|
||||
expect(statusBadgeClass('whatever')).toBe('status-badge')
|
||||
})
|
||||
})
|
||||
@@ -32,8 +32,8 @@ export function getLatestStable(releases: Release[]): Release | undefined {
|
||||
|
||||
const STATUS_BADGE_CLASS: Record<string, string> = {
|
||||
released: 'status-badge status-released',
|
||||
demo: 'status-badge',
|
||||
development: 'status-badge',
|
||||
demo: 'status-badge status-demo',
|
||||
development: 'status-badge status-development',
|
||||
archived: 'status-badge',
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(info, platform) in data.platforms" :key="platform" class="builds-row">
|
||||
<td class="builds-td-engine">{{ info.label }}</td>
|
||||
<td class="builds-td-engine">
|
||||
<span class="builds-engine"><PlatformIcon :platform="platform as string" />{{ info.label }}</span>
|
||||
</td>
|
||||
<template v-for="group in columnGroups" :key="group.label">
|
||||
<td
|
||||
v-for="(col, colIdx) in group.kinds" :key="col.kind"
|
||||
@@ -58,7 +60,9 @@
|
||||
|
||||
<div v-if="data" class="builds-mobile">
|
||||
<div v-for="(info, platform) in data.platforms" :key="platform" class="builds-card">
|
||||
<h2 class="builds-card-title">{{ info.label }}</h2>
|
||||
<h2 class="builds-card-title">
|
||||
<PlatformIcon :platform="platform as string" />{{ info.label }}
|
||||
</h2>
|
||||
<div v-for="group in columnGroups" :key="group.label" class="builds-card-group">
|
||||
<h3 class="builds-card-group-header">{{ group.label }}</h3>
|
||||
<div class="builds-card-kinds">
|
||||
@@ -86,6 +90,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { Check, X } from 'lucide-vue-next'
|
||||
import { useBuildsStore } from '../../stores/builds.store'
|
||||
import SkeletonCard from '../../components/SkeletonCard.vue'
|
||||
import PlatformIcon from '../../components/PlatformIcon.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -170,6 +175,10 @@ onMounted(() => store.fetch())
|
||||
.builds-td-engine {
|
||||
@apply whitespace-nowrap px-5 py-3 font-medium text-fg;
|
||||
}
|
||||
.builds-engine,
|
||||
.builds-card-title {
|
||||
@apply flex items-center gap-2;
|
||||
}
|
||||
.builds-td-kind {
|
||||
@apply px-3 py-3 text-center;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
</article>
|
||||
|
||||
<article class="channel">
|
||||
<h3 class="channel-title">IRC</h3>
|
||||
<h3 class="channel-title"><Terminal v-bind="ICON" />IRC</h3>
|
||||
<p class="channel-desc">{{ t('contact.irc.desc') }}</p>
|
||||
<dl class="channel-facts">
|
||||
<dt>Network</dt><dd class="mono">Libera.Chat</dd>
|
||||
@@ -41,7 +41,7 @@
|
||||
</article>
|
||||
|
||||
<article class="channel">
|
||||
<h3 class="channel-title">BBS</h3>
|
||||
<h3 class="channel-title"><RadioTower v-bind="ICON" />BBS</h3>
|
||||
<p class="channel-desc">{{ t('contact.bbs.desc') }}</p>
|
||||
<dl class="channel-facts">
|
||||
<dt>Host</dt><dd class="mono">games.teletype.hu</dd>
|
||||
@@ -88,7 +88,8 @@
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { CONFIG } from '../../lib/config'
|
||||
import MediaBand from '../../components/MediaBand.vue'
|
||||
import { BrandIcon } from '../../components/icons'
|
||||
import { RadioTower, Terminal } from 'lucide-vue-next'
|
||||
import { BrandIcon, ICON } from '../../components/icons'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
||||
@@ -127,7 +127,15 @@ button:focus-visible {
|
||||
}
|
||||
|
||||
.status-released {
|
||||
@apply border-accent/40 bg-accent-quiet text-accent;
|
||||
@apply border-accent/40 bg-accent/15 text-accent;
|
||||
}
|
||||
|
||||
.status-demo {
|
||||
@apply border-info/40 bg-info/15 text-info;
|
||||
}
|
||||
|
||||
.status-development {
|
||||
@apply border-warn/40 bg-warn/15 text-warn;
|
||||
}
|
||||
|
||||
.mono {
|
||||
|
||||
@@ -229,6 +229,16 @@
|
||||
background-color: #00a800 !important;
|
||||
}
|
||||
|
||||
.retro-mode .status-demo {
|
||||
background-color: #0000a8 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.retro-mode .status-development {
|
||||
background-color: #a85400 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.retro-mode table {
|
||||
border: 2px solid #a8a8a8 !important;
|
||||
border-collapse: collapse !important;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
--c-accent-fg: 255 255 255;
|
||||
--c-accent-quiet: 220 252 231;
|
||||
|
||||
--c-info: 29 78 216;
|
||||
--c-warn: 180 83 9;
|
||||
--c-danger: 185 28 28;
|
||||
}
|
||||
@@ -36,6 +37,7 @@
|
||||
--c-accent-fg: 9 9 11;
|
||||
--c-accent-quiet: 20 83 45;
|
||||
|
||||
--c-info: 96 165 250;
|
||||
--c-warn: 255 176 0;
|
||||
--c-danger: 248 113 113;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ module.exports = {
|
||||
'accent-hover': token('--c-accent-hover'),
|
||||
'accent-fg': token('--c-accent-fg'),
|
||||
'accent-quiet': token('--c-accent-quiet'),
|
||||
info: token('--c-info'),
|
||||
warn: token('--c-warn'),
|
||||
danger: token('--c-danger'),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user