Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions _config_theme.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ navbar-links:
- GitHub: "https://github.com/sponsors/LizardByte"
- Patreon: "https://patreon.com/LizardByte"
- PayPal: "https://www.paypal.com/paypalme/ReenigneArcher"
Store: "store"
Resources:
- Blog: "blog"
- Community: "https://github.com/orgs/LizardByte/discussions"
Expand Down
2 changes: 1 addition & 1 deletion _data/amazon_products.yml
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@
# Accessories
- title: >-
Elgato Stream Deck MK.2 –
Studio Controller, 15 macro keys, trigger actions in apps and software like OBS, Twitch, YouTube and more,
Studio Controller, 15 macro keys, trigger actions in apps and software like OBS, Twitch, YouTube and more,
works with Mac and PC
image: "https://m.media-amazon.com/images/I/61gtdFnK+UL._AC_SL1500_.jpg"
link: "https://www.amazon.com/dp/B09738CV2G"
Expand Down
49 changes: 49 additions & 0 deletions _data/store_products.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
- id: virtual-hid-driver
name: Virtual HID Driver
category: Windows software
tagline: Modern virtual gamepads for Sunshine on Windows
description: >-
Unlock expanded virtual controller support in Sunshine with a user-mode driver built and maintained alongside
the rest of the LizardByte input stack.
cover:
src: https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/libvirtualhid-poster-1440x2160.png
alt: A green outline of a game controller on a vertical dark green background
aspect: portrait
screenshots:
- src: "https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/docs/images/screenshots/\
libvirtualhid-control-03.png"
alt: libvirtualhid control displaying an active Xbox Series virtual controller
caption: Inspect virtual controller input, battery state, and output reports.
- src: "https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/docs/images/screenshots/\
libvirtualhid-control-04.png"
alt: libvirtualhid control displaying a DualSense virtual controller
caption: Use controller-specific features such as touchpad input and RGB output.
- src: "https://raw.githubusercontent.com/LizardByte/libvirtualhid/refs/heads/master/docs/images/screenshots/\
windows-driver-game-controllers-and-properties.png"
alt: Windows Game Controllers and controller properties showing a Virtual HID Framework device
caption: Virtual controllers appear in the familiar Windows Game Controllers panel.
badges:
- label: Windows
icon: fa-brands fa-windows
- label: Sunshine compatible
icon: fa-solid fa-sun
prices:
- amount: $14.99
label: per year
- amount: $49.99
label: lifetime
price_note: One license can be activated on up to five machines.
features:
- Generic, Xbox One, Xbox Series, DualShock 4, DualSense, and Switch Pro-style profiles
- Support for advanced controller features when the selected controller and game provide them
- Ongoing driver maintenance and improvements alongside Sunshine and other LizardByte software
details:
label: Learn more
url: https://app.lizardbyte.dev/libvirtualhid/virtual-hid-driver
offers:
- label: Purchase
url: https://buy.polar.sh/polar_cl_zj6Io5NVukXfZSl97ULtFvImfI5L1jbL2cSnc0Y72Pt
store: Polar
external: true
icon: fa-solid fa-cart-shopping
200 changes: 200 additions & 0 deletions _includes/store-product-card.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
{% assign product = include.product %}
<article class="store-product-card{% if include.featured %} store-product-card-featured{% endif %}">
<div class="store-product-summary">
<div class="store-product-media store-product-media-{{ product.cover.aspect | default: 'landscape' }}">
<a href="{{ product.details.url }}" aria-label="Learn more about {{ product.name | escape }}">
<img
class="store-product-image crowdin-ignore"
src="{{ product.cover.src }}"
alt="{{ product.cover.alt | escape }}"
loading="lazy"
>
</a>
{% if product.badges %}
<ul class="store-product-badges list-unstyled" aria-label="Product compatibility">
{% for badge in product.badges %}
<li class="store-product-badge">
{% if badge.icon %}<i class="{{ badge.icon }}" aria-hidden="true"></i>{% endif %}
{{ badge.label }}
</li>
{% endfor %}
</ul>
{% endif %}
</div>

<div class="store-product-content">
<div class="store-product-details">
<div class="store-product-heading">
<span class="store-product-category">{{ product.category }}</span>
<h3 class="store-product-title">{{ product.name }}</h3>
<p class="store-product-tagline">{{ product.tagline }}</p>
</div>

<p class="store-product-description">{{ product.description }}</p>

{% if product.features %}
<ul class="store-product-features">
{% for feature in product.features %}
<li>
<i class="fa-solid fa-circle-check" aria-hidden="true"></i>
<span>{{ feature }}</span>
</li>
{% endfor %}
</ul>
{% endif %}
</div>

<div class="store-product-purchase">
{% if product.prices %}
<div class="store-product-prices" aria-label="Pricing options">
{% for price in product.prices %}
<div class="store-price-option">
<span class="store-price-amount crowdin-ignore">{{ price.amount }}</span>
<span class="store-price-label">{{ price.label }}</span>
</div>
{% endfor %}
</div>
{% endif %}

{% if product.price_note %}
<p class="store-product-price-note">
<i class="fa-solid fa-display" aria-hidden="true"></i>
{{ product.price_note }}
</p>
{% endif %}

<div class="store-product-actions">
{% for offer in product.offers %}
<a
class="btn btn-primary"
href="{{ offer.url }}"
{% if offer.external %}
target="_blank"
rel="noopener"
{% endif %}
>
{% if offer.icon %}<i class="{{ offer.icon }}" aria-hidden="true"></i>{% endif %}
{{ offer.label }}
<span class="visually-hidden">
for {{ product.name }}{% if offer.store %} from {{ offer.store }}{% endif %}
</span>
</a>
{% endfor %}
{% if product.details %}
<a class="btn btn-outline-theme" href="{{ product.details.url }}">
{{ product.details.label }}
<i class="fa-solid fa-arrow-right" aria-hidden="true"></i>
</a>
{% endif %}
</div>

{% for offer in product.offers %}
{% if offer.store %}
<p class="store-product-seller">
<i class="fa-solid fa-lock" aria-hidden="true"></i>
Checkout provided by {{ offer.store }}
</p>
{% endif %}
{% endfor %}
</div>
</div>
</div>

{% if product.screenshots %}
<section class="store-product-gallery" aria-labelledby="{{ product.id }}-screenshots">
<div class="store-product-gallery-heading">
<span class="store-product-category">Gallery</span>
<h4 id="{{ product.id }}-screenshots">Screenshots</h4>
</div>
<div class="store-screenshot-grid">
{% for screenshot in product.screenshots %}
<button
class="store-screenshot-thumbnail"
type="button"
data-bs-toggle="modal"
data-bs-target="#{{ product.id }}-gallery"
data-store-slide="{{ forloop.index0 }}"
aria-label="View screenshot {{ forloop.index }} of {{ product.screenshots.size }}: {{ screenshot.alt | escape }}"
>
<img
class="crowdin-ignore"
src="{{ screenshot.src }}"
alt=""
loading="lazy"
>
<span class="store-screenshot-expand" aria-hidden="true">
<i class="fa-solid fa-expand"></i>
</span>
</button>
{% endfor %}
</div>
</section>
{% endif %}
</article>

{% if product.screenshots %}
<div
class="modal fade store-gallery-modal"
id="{{ product.id }}-gallery"
tabindex="-1"
aria-labelledby="{{ product.id }}-gallery-title"
aria-hidden="true"
>
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="{{ product.id }}-gallery-title">
{{ product.name }} screenshots
</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div
class="carousel slide store-gallery-carousel"
id="{{ product.id }}-carousel"
data-bs-interval="false"
data-bs-keyboard="true"
tabindex="-1"
aria-label="{{ product.name | escape }} screenshot viewer"
>
<div class="carousel-inner">
{% for screenshot in product.screenshots %}
<figure class="carousel-item{% if forloop.first %} active{% endif %}">
<img
class="store-gallery-image crowdin-ignore"
src="{{ screenshot.src }}"
alt="{{ screenshot.alt | escape }}"
>
{% if screenshot.caption %}
<figcaption class="store-gallery-caption">{{ screenshot.caption }}</figcaption>
{% endif %}
</figure>
{% endfor %}
</div>

{% if product.screenshots.size > 1 %}
<button
class="carousel-control-prev"
type="button"
data-bs-target="#{{ product.id }}-carousel"
data-bs-slide="prev"
>
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous screenshot</span>
</button>
<button
class="carousel-control-next"
type="button"
data-bs-target="#{{ product.id }}-carousel"
data-bs-slide="next"
>
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next screenshot</span>
</button>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
Loading