fix font
This commit is contained in:
Binary file not shown.
1
public/icon/font.svg
Normal file
1
public/icon/font.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M349.1 114.7C343.9 103.3 332.5 96 320 96C307.5 96 296.1 103.3 290.9 114.7L123.5 480L112 480C94.3 480 80 494.3 80 512C80 529.7 94.3 544 112 544L200 544C217.7 544 232 529.7 232 512C232 494.3 217.7 480 200 480L193.9 480L215.9 432L424.2 432L446.2 480L440.1 480C422.4 480 408.1 494.3 408.1 512C408.1 529.7 422.4 544 440.1 544L528.1 544C545.8 544 560.1 529.7 560.1 512C560.1 494.3 545.8 480 528.1 480L516.6 480L349.2 114.7zM394.8 368L245.2 368L320 204.8L394.8 368z"/></svg>
|
||||
|
After Width: | Height: | Size: 689 B |
@@ -3,6 +3,12 @@ import { isLoggedIn } from '../lib/auth'
|
||||
|
||||
let currentNetwork = 'bsky.social'
|
||||
let currentLang = localStorage.getItem('preferred-lang') || 'en'
|
||||
let currentFont = localStorage.getItem('preferred-font') || 'system'
|
||||
|
||||
const FONT_OPTIONS: { id: string; label: string }[] = [
|
||||
{ id: 'system', label: 'System' },
|
||||
{ id: 'aifont', label: 'aifont' },
|
||||
]
|
||||
|
||||
export function getCurrentNetwork(): string {
|
||||
return currentNetwork
|
||||
@@ -52,17 +58,52 @@ export function renderModeTabs(handle: string, activeTab: 'blog' | 'browser' | '
|
||||
return `<div class="mode-tabs"><div class="tabs-scroll">${tabs}</div>${pdsSelector}</div>`
|
||||
}
|
||||
|
||||
export function getCurrentFont(): string {
|
||||
return currentFont
|
||||
}
|
||||
|
||||
export function setCurrentFont(font: string): void {
|
||||
currentFont = font
|
||||
localStorage.setItem('preferred-font', font)
|
||||
}
|
||||
|
||||
function applyFont(font: string): void {
|
||||
// Remove all font-* classes
|
||||
for (const f of FONT_OPTIONS) {
|
||||
document.body.classList.remove(`font-${f.id}`)
|
||||
}
|
||||
// Add selected (skip system = no class)
|
||||
if (font !== 'system') {
|
||||
document.body.classList.add(`font-${font}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Render language selector (above content)
|
||||
export function renderLangSelector(langs: string[]): string {
|
||||
if (langs.length < 2) return ''
|
||||
|
||||
return `
|
||||
const langHtml = langs.length >= 2 ? `
|
||||
<div class="lang-selector" id="lang-selector">
|
||||
<button type="button" class="lang-btn" id="lang-tab">
|
||||
<img src="/icon/language.svg" alt="Lang" class="lang-icon">
|
||||
</button>
|
||||
<div class="lang-dropdown" id="lang-dropdown"></div>
|
||||
</div>
|
||||
` : ''
|
||||
|
||||
const fontHtml = renderFontToggle()
|
||||
|
||||
if (!langHtml && !fontHtml) return ''
|
||||
return `<div class="content-header">${fontHtml}${langHtml}</div>`
|
||||
}
|
||||
|
||||
// Render font selector with dropdown
|
||||
export function renderFontToggle(): string {
|
||||
return `
|
||||
<div class="font-selector" id="font-selector">
|
||||
<button type="button" class="font-btn ${currentFont !== 'system' ? 'active' : ''}" id="font-tab">
|
||||
<img src="/icon/font.svg" alt="Font" class="font-icon">
|
||||
</button>
|
||||
<div class="font-dropdown" id="font-dropdown"></div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
@@ -157,9 +198,54 @@ export async function setupModeTabs(onNetworkChange: (network: string) => void,
|
||||
})
|
||||
}
|
||||
|
||||
// Setup font selector
|
||||
const fontTab = document.getElementById('font-tab')
|
||||
const fontDropdown = document.getElementById('font-dropdown')
|
||||
|
||||
if (fontTab && fontDropdown) {
|
||||
// Apply saved font on load
|
||||
applyFont(currentFont)
|
||||
|
||||
// Build font options
|
||||
const fontOptionsHtml = FONT_OPTIONS.map(f => {
|
||||
const isSelected = f.id === currentFont
|
||||
return `
|
||||
<div class="font-option ${isSelected ? 'selected' : ''}" data-font="${f.id}">
|
||||
<span class="font-name">${f.label}</span>
|
||||
<span class="font-check">\u2713</span>
|
||||
</div>
|
||||
`
|
||||
}).join('')
|
||||
|
||||
fontDropdown.innerHTML = fontOptionsHtml
|
||||
|
||||
// Toggle dropdown
|
||||
fontTab.addEventListener('click', (e) => {
|
||||
e.stopPropagation()
|
||||
fontDropdown.classList.toggle('show')
|
||||
})
|
||||
|
||||
// Handle option selection
|
||||
fontDropdown.querySelectorAll('.font-option').forEach(opt => {
|
||||
opt.addEventListener('click', (e) => {
|
||||
e.stopPropagation()
|
||||
const font = (opt as HTMLElement).dataset.font || 'system'
|
||||
|
||||
applyFont(font)
|
||||
setCurrentFont(font)
|
||||
fontTab.classList.toggle('active', font !== 'system')
|
||||
|
||||
fontDropdown.querySelectorAll('.font-option').forEach(o => o.classList.remove('selected'))
|
||||
opt.classList.add('selected')
|
||||
fontDropdown.classList.remove('show')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Close dropdowns on outside click
|
||||
document.addEventListener('click', () => {
|
||||
pdsDropdown?.classList.remove('show')
|
||||
langDropdown?.classList.remove('show')
|
||||
fontDropdown?.classList.remove('show')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -885,6 +885,12 @@ async function render(route: Route): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
// Apply saved font preference immediately
|
||||
const savedFont = localStorage.getItem('preferred-font')
|
||||
if (savedFont && savedFont !== 'system') {
|
||||
document.body.classList.add(`font-${savedFont}`)
|
||||
}
|
||||
|
||||
// Initial render
|
||||
render(parseRoute())
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'aifont', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #1a1a1a;
|
||||
background: #fff;
|
||||
@@ -1506,9 +1506,151 @@ body {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* Font Toggle */
|
||||
.font-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.font-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
.font-btn:hover {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.font-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.font-btn:hover .font-icon {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.font-btn.active .font-icon {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.font-selector {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.font-dropdown {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 4px;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
min-width: 100px;
|
||||
z-index: 100;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.font-dropdown.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.font-option {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.font-option:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.font-option.selected {
|
||||
background: linear-gradient(135deg, #f0f7ff 0%, #e8f4ff 100%);
|
||||
}
|
||||
|
||||
.font-name {
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.font-check {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #ccc;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 10px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.font-option.selected .font-check {
|
||||
background: var(--btn-color);
|
||||
border-color: var(--btn-color);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.font-option:not(.selected) .font-check {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
/* Font class on body */
|
||||
body.font-aifont {
|
||||
font-family: 'aifont', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
||||
letter-spacing: -0.08em;
|
||||
}
|
||||
|
||||
body.font-aifont code,
|
||||
body.font-aifont pre,
|
||||
body.font-aifont kbd,
|
||||
body.font-aifont samp {
|
||||
letter-spacing: normal;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.font-btn:hover {
|
||||
background: #2a2a2a;
|
||||
}
|
||||
.font-icon {
|
||||
filter: invert(0.7);
|
||||
}
|
||||
.font-btn.active .font-icon {
|
||||
filter: invert(1);
|
||||
}
|
||||
.font-dropdown {
|
||||
background: #1a1a1a;
|
||||
border-color: #333;
|
||||
}
|
||||
.font-option:hover {
|
||||
background: #2a2a2a;
|
||||
}
|
||||
.font-option.selected {
|
||||
background: linear-gradient(135deg, #1a2a3a 0%, #1a3040 100%);
|
||||
}
|
||||
.font-name {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.lang-btn {
|
||||
background: transparent;
|
||||
|
||||
Reference in New Issue
Block a user