Skip to content

Commit b3b4553

Browse files
Merge branch 'feat/hardware-signer-connection-filter'
2 parents a876b98 + fd49b08 commit b3b4553

26 files changed

Lines changed: 347 additions & 3 deletions

assets/js/main.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,79 @@ const setupMultiCarousels = () => {
246246
carousels.forEach(setupMultiScroller)
247247
}
248248

249+
const setupHardwareSignerFilters = () => {
250+
const filterRoots = document.querySelectorAll('[data-hardware-signer-filter]')
251+
252+
filterRoots.forEach((root) => {
253+
if (root.dataset.filterBound === 'true') {
254+
return
255+
}
256+
257+
const buttons = Array.from(root.querySelectorAll('[data-connection-type]'))
258+
const cards = Array.from(root.querySelectorAll('[data-hardware-signer-card]'))
259+
const emptyState = root.querySelector('[data-hardware-signer-empty]')
260+
261+
if (!buttons.length || !cards.length || !emptyState) {
262+
return
263+
}
264+
265+
root.dataset.filterBound = 'true'
266+
267+
const setButtonState = (button, isActive) => {
268+
button.setAttribute('aria-pressed', isActive ? 'true' : 'false')
269+
button.classList.toggle('is-active', isActive)
270+
button.classList.toggle('is-inactive', !isActive)
271+
}
272+
273+
const getActiveTypes = () => new Set(
274+
buttons
275+
.filter(button => button.getAttribute('aria-pressed') === 'true')
276+
.map(button => button.dataset.connectionType)
277+
.filter(Boolean)
278+
)
279+
280+
const updateCards = () => {
281+
const activeTypes = getActiveTypes()
282+
let visibleCount = 0
283+
284+
cards.forEach((card) => {
285+
const supportedTypes = (card.dataset.connectionTypes || '')
286+
.split(',')
287+
.map(type => type.trim())
288+
.filter(Boolean)
289+
290+
const isVisible = activeTypes.size > 0 && supportedTypes.some(type => activeTypes.has(type))
291+
card.hidden = !isVisible
292+
293+
if (isVisible) {
294+
visibleCount += 1
295+
}
296+
})
297+
298+
emptyState.hidden = visibleCount > 0
299+
}
300+
301+
buttons.forEach((button) => {
302+
setButtonState(button, true)
303+
button.addEventListener('click', () => {
304+
const isActive = button.getAttribute('aria-pressed') === 'true'
305+
setButtonState(button, !isActive)
306+
updateCards()
307+
})
308+
})
309+
310+
updateCards()
311+
})
312+
}
313+
249314
if (document.readyState === 'loading') {
250315
document.addEventListener('DOMContentLoaded', () => {
251316
setupMultiCarousels()
252317
setupCodeCopyButtons()
318+
setupHardwareSignerFilters()
253319
})
254320
} else {
255321
setupMultiCarousels()
256322
setupCodeCopyButtons()
323+
setupHardwareSignerFilters()
257324
}

assets/sass/styles.scss

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,89 @@ table img {
120120
flex: 0 0 calc((100% - (var(--carousel-gap, 1rem) * (var(--carousel-per-slide) - 1))) / var(--carousel-per-slide));
121121
}
122122

123+
.hardware-signer-filter-bar {
124+
display: flex;
125+
flex-wrap: wrap;
126+
align-items: center;
127+
gap: 0.9rem;
128+
}
129+
130+
.hardware-signer-filter-label {
131+
color: var(--bs-secondary-color);
132+
font-size: 0.95rem;
133+
font-weight: 600;
134+
}
135+
136+
.hardware-signer-filter-buttons {
137+
display: flex;
138+
flex-wrap: wrap;
139+
gap: 0.5rem;
140+
}
141+
142+
.hardware-signer-filter-btn {
143+
display: inline-flex;
144+
align-items: center;
145+
gap: 6px;
146+
padding: 4px 10px;
147+
border: 1px solid #cbd5e1;
148+
border-radius: 999px;
149+
background: #fff;
150+
color: #334155;
151+
font-size: 0.85rem;
152+
font-weight: 600;
153+
line-height: 1;
154+
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
155+
}
156+
157+
.hardware-signer-filter-btn:hover {
158+
transform: translateY(-1px);
159+
}
160+
161+
.hardware-signer-filter-btn:focus-visible {
162+
outline: none;
163+
box-shadow: 0 0 0 0.22rem rgba(117, 49, 249, 0.22);
164+
}
165+
166+
.hardware-signer-filter-btn.is-active {
167+
border-color: #7531f9;
168+
background: #7531f9;
169+
color: #fff;
170+
}
171+
172+
.hardware-signer-filter-btn.is-inactive {
173+
background: #f8fafc;
174+
color: #475569;
175+
}
176+
177+
.hardware-signer-filter-icon {
178+
width: 1.2em;
179+
height: 1.2em;
180+
filter: brightness(0) saturate(100%) invert(25%) sepia(12%) saturate(903%) hue-rotate(176deg) brightness(95%) contrast(88%);
181+
}
182+
183+
.hardware-signer-filter-btn.is-active .hardware-signer-filter-icon {
184+
filter: brightness(0) saturate(100%) invert(100%);
185+
}
186+
187+
.hardware-signer-card[hidden] {
188+
display: none !important;
189+
}
190+
191+
.hardware-signer-filter-empty {
192+
font-size: 0.95rem;
193+
}
194+
195+
@media (max-width: 575.98px) {
196+
.hardware-signer-filter-btn {
197+
width: 100%;
198+
justify-content: center;
199+
}
200+
201+
.hardware-signer-filter-buttons {
202+
width: 100%;
203+
}
204+
}
205+
123206
.highlight {
124207
position: relative;
125208

i18n/ar.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*اختبار*، *اختبار*، *اختبا
2121
donate_support_other_ways: "أو ابحث عن طرق أخرى لجعل **Bitcoin Safe** أفضل للجميع"
2222
hardware_badge_bitcoin_only: "Bitcoin-only"
2323
hardware_badge_bitcoin_only_available: "إصدار Bitcoin-only متاح"
24+
hardware_filter_label: "تصفية حسب نوع الاتصال"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "لا يوجد جهاز توقيع يطابق أنواع الاتصال المحددة."

i18n/ca.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*proves*, *proves*, *proves*, i envia nous inf
2121
donate_support_other_ways: "o troba altres maneres de fer **Bitcoin Safe** millor per a tothom"
2222
hardware_badge_bitcoin_only: "Només Bitcoin"
2323
hardware_badge_bitcoin_only_available: "Opció només Bitcoin disponible"
24+
hardware_filter_label: "Filtra per tipus de connexió"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "Cap signant coincideix amb els tipus de connexió seleccionats."

i18n/de.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*testen*, *testen*, *testen* und neue Bug-Repo
2121
donate_support_other_ways: "oder finde andere Wege, **Bitcoin Safe** für alle besser zu machen"
2222
hardware_badge_bitcoin_only: "Nur Bitcoin"
2323
hardware_badge_bitcoin_only_available: "Nur-Bitcoin-Option verfügbar"
24+
hardware_filter_label: "Nach Verbindung filtern"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "Keine Signer passen zu den ausgewählten Verbindungstypen."

i18n/en.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*testing*, *testing*, *testing*, and submit ne
2121
donate_support_other_ways: "or find other ways to make **Bitcoin Safe** better for everyone"
2222
hardware_badge_bitcoin_only: "Bitcoin-only"
2323
hardware_badge_bitcoin_only_available: "Bitcoin-only available"
24+
hardware_filter_label: "Filter by connection type"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "No signers match the selected connection types."

i18n/es.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*pruebas*, *pruebas*, *pruebas*, y envía nuev
2121
donate_support_other_ways: "o encuentra otras formas de hacer **Bitcoin Safe** mejor para todos"
2222
hardware_badge_bitcoin_only: "Solo Bitcoin"
2323
hardware_badge_bitcoin_only_available: "Opción solo Bitcoin disponible"
24+
hardware_filter_label: "Filtrar por tipo de conexión"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "Ningún firmante coincide con los tipos de conexión seleccionados."

i18n/fa.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*تست*، *تست*، *تست*، و گزارش
2121
donate_support_other_ways: "یا راه‌های دیگری برای بهتر کردن **Bitcoin Safe** برای همه پیدا کنید"
2222
hardware_badge_bitcoin_only: "فقط بیت‌کوین"
2323
hardware_badge_bitcoin_only_available: "گزینه فقط بیت‌کوین موجود است"
24+
hardware_filter_label: "فیلتر بر اساس نوع اتصال"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "هیچ امضاکننده‌ای با انواع اتصال انتخاب‌شده مطابقت ندارد."

i18n/fr.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*tester*, *tester*, *tester*, et envoyer de no
2121
donate_support_other_ways: "ou trouve d'autres moyens d'améliorer **Bitcoin Safe** pour tout le monde"
2222
hardware_badge_bitcoin_only: "Bitcoin uniquement"
2323
hardware_badge_bitcoin_only_available: "Option Bitcoin uniquement disponible"
24+
hardware_filter_label: "Filtrer par type de connexion"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "Aucun signataire ne correspond aux types de connexion sélectionnés."

i18n/hi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ donate_support_testing_feedback: "*टेस्टिंग*, *टेस्ट
2121
donate_support_other_ways: "या **Bitcoin Safe** को सभी के लिए बेहतर बनाने के अन्य तरीके खोजें"
2222
hardware_badge_bitcoin_only: "केवल Bitcoin"
2323
hardware_badge_bitcoin_only_available: "केवल Bitcoin विकल्प उपलब्ध"
24+
hardware_filter_label: "कनेक्शन प्रकार के अनुसार फ़िल्टर करें"
25+
hardware_filter_usb: "USB"
26+
hardware_filter_qr: "QR"
27+
hardware_filter_sd: "SD"
28+
hardware_filter_bluetooth: "Bluetooth"
29+
hardware_filter_empty: "चुने गए कनेक्शन प्रकारों से मेल खाने वाला कोई साइनर नहीं मिला।"

0 commit comments

Comments
 (0)