UI
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
<a class="button button-primary" href="#start-here">Explore the projects</a>
|
||||
<a class="button button-secondary" href="https://discourse.eom.dev/latest">Join the conversation</a>
|
||||
<a class="button button-secondary" href="/members/register/">Create an eom.dev account</a>
|
||||
<a class="quiet-link" href="#services">Browse community services</a>
|
||||
</div>
|
||||
<p class="hero-note">Independent software, open-source projects, music, and games—made in Raleigh, North Carolina.</p>
|
||||
</div>
|
||||
@@ -94,6 +95,65 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="services" aria-labelledby="services-title">
|
||||
<div class="section-heading">
|
||||
<p class="eyebrow">One account, a community of services</p>
|
||||
<h2 id="services-title">Find your place on eom.dev</h2>
|
||||
<p>A free account includes forums, chat, Git hosting and hosted games. Gold (Level 3) and above add Mastodon and PeerTube account access. Public posts and videos can still be browsed without a paid membership.</p>
|
||||
</div>
|
||||
<div class="project-grid">
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Free · Level 0 and above</p>
|
||||
<h3>Discourse · Forums</h3>
|
||||
<p>Ask questions, share projects and join longer conversations. Bronze and above also get exclusive member content.</p>
|
||||
<a class="text-link" href="https://discourse.eom.dev/">Visit Discourse <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Free · Level 0 and above</p>
|
||||
<h3>Matrix · Chat</h3>
|
||||
<p>Keep in touch in community rooms through Element. Bronze and above also get exclusive member content.</p>
|
||||
<a class="text-link" href="https://element.eom.dev/">Open Matrix chat <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Free · Level 0 and above</p>
|
||||
<h3>Gitea · Git hosting</h3>
|
||||
<p>Host code, collaborate on repositories and explore the projects behind the lab.</p>
|
||||
<a class="text-link" href="https://gitea.eom.dev/">Explore Gitea <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Free · Level 0 and above</p>
|
||||
<h3>Hosted games</h3>
|
||||
<p>Join community games, including Luanti, and try The Button. No paid membership is needed; exclusive higher-tier servers are not currently offered.</p>
|
||||
<div class="project-links"><a class="text-link" href="https://discourse.eom.dev/c/gaming/23">Find a game</a><a class="text-link" href="https://button.eom.dev/">Play The Button</a></div>
|
||||
</article>
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Gold · Levels 3–5</p>
|
||||
<h3>Mastodon · Social networking</h3>
|
||||
<p>Participate with an eom.dev Mastodon account and connect with the wider fediverse.</p>
|
||||
<a class="text-link" href="https://mastodon.eom.dev/">Visit Mastodon <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Gold · Levels 3–5</p>
|
||||
<h3>PeerTube · Video sharing</h3>
|
||||
<p>Use an eom.dev PeerTube account to take part in the video community. Public recordings remain available to watch.</p>
|
||||
<a class="text-link" href="https://peertube.eom.dev/">Visit PeerTube <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Included with your free account</p>
|
||||
<h3>Dex · Shared sign-in</h3>
|
||||
<p>Use the same eom.dev identity across compatible services. Dex handles sign-in; start from the service you want to use.</p>
|
||||
<a class="text-link" href="/members/register/">Create your account <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
<article class="project-card">
|
||||
<p class="card-kicker">Public live channel</p>
|
||||
<h3>Owncast · Live streams</h3>
|
||||
<p>Watch live performances, experiments and work in progress when the channel is on air.</p>
|
||||
<a class="text-link" href="https://owncast.eom.dev/">Watch Owncast <span aria-hidden="true">→</span></a>
|
||||
</article>
|
||||
</div>
|
||||
<p><a class="text-link" href="/members/">Compare membership benefits and included services <span aria-hidden="true">→</span></a></p>
|
||||
</section>
|
||||
|
||||
<section class="community-band" aria-labelledby="community-title">
|
||||
<div>
|
||||
<p class="eyebrow">Built in public</p>
|
||||
|
||||
@@ -81,6 +81,59 @@ class ServiceGroupLDAPIntegrationTests(TestCase):
|
||||
|
||||
@override_settings(MEMBERSHIP_TIERS=TIERS)
|
||||
class ServiceDisplayTests(TestCase):
|
||||
def test_published_tier_copy_matches_role_defaults(self):
|
||||
root = Path(__file__).absolute().parents[3]
|
||||
tiers = json.loads((root / "membership/tiers.eom.json").read_text(encoding="utf-8"))
|
||||
role = root.parent / "ansible-role-www/defaults/main.yml"
|
||||
if not role.exists():
|
||||
self.skipTest("Role checkout is not present in the application test image")
|
||||
import yaml
|
||||
|
||||
deployed = yaml.safe_load(role.read_text(encoding="utf-8"))["www_membership_tiers"]
|
||||
for key, tier in tiers.items():
|
||||
self.assertEqual(tier["description"], deployed[key]["description"])
|
||||
self.assertEqual(tier["benefits"], deployed[key]["benefits"])
|
||||
|
||||
def test_homepage_lists_services_with_clear_access_labels(self):
|
||||
root = Path(__file__).absolute().parents[3]
|
||||
homepage = root / "htdocs/index.html"
|
||||
if not homepage.exists():
|
||||
self.skipTest("Static website checkout is not present in the application test image")
|
||||
from html.parser import HTMLParser
|
||||
|
||||
class DirectoryParser(HTMLParser):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.active = False
|
||||
self.text = []
|
||||
self.links = []
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
attributes = dict(attrs)
|
||||
if tag == "section" and attributes.get("id") == "services":
|
||||
self.active = True
|
||||
if self.active and tag == "a":
|
||||
self.links.append(attributes.get("href"))
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
if tag == "section":
|
||||
self.active = False
|
||||
|
||||
def handle_data(self, data):
|
||||
if self.active:
|
||||
self.text.append(data)
|
||||
|
||||
parser = DirectoryParser()
|
||||
parser.feed(homepage.read_text(encoding="utf-8"))
|
||||
text = " ".join(parser.text)
|
||||
for name in ("Dex", "Discourse", "Matrix", "Gitea", "Mastodon", "PeerTube", "Hosted games", "Owncast"):
|
||||
self.assertIn(name, text)
|
||||
self.assertIn("Free · Level 0 and above", text)
|
||||
self.assertIn("Gold · Levels 3–5", text)
|
||||
self.assertIn("not currently offered", text)
|
||||
self.assertIn("/members/", parser.links)
|
||||
self.assertIn("https://element.eom.dev/", parser.links)
|
||||
|
||||
@override_settings(MEMBERSHIP_SERVICE_GROUPS={
|
||||
"0": ["cn=Dex Users," + BASE, "cn=Matrix Users," + BASE],
|
||||
"1": ["cn=Gitea Users," + BASE],
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<section class="member-hero">
|
||||
<p class="eyebrow">Keep your own corner of the internet alive</p>
|
||||
<h1>A place to belong.<br>A way to give back.</h1>
|
||||
<p class="member-intro">A private place to connect, a closer look at what is being made, and opportunities to help shape it. Start with a free eom.dev account, then choose an optional membership to support the independent work.</p>
|
||||
<p class="member-intro">Join free for community services and games. Choose a paid tier for exclusive content, previews and a closer say in what comes next.</p>
|
||||
{% if account %}
|
||||
<div class="member-panel account-panel">
|
||||
<div><p class="eyebrow">Your eom.dev account · Membership level {{ account.membership_level }}</p><h2>{{ account.uid }}</h2><p>{{ account.email }}</p></div>
|
||||
@@ -73,15 +73,15 @@
|
||||
<div class="member-grid">
|
||||
<article class="member-panel tier-card free-tier">
|
||||
<p class="card-kicker">Level 0 · The starting point</p><h3>Open Lab</h3><p class="tier-price">Free <span>/ always</span></p>
|
||||
<p>One account for eom.dev, its community, and its services.</p>
|
||||
<ul><li>No payment required</li><li>Access to games hosted on eom.dev</li><li>One account for compatible community services</li><li>Giveaways exclusive to Open Lab members</li><li>Upgrade whenever you choose</li></ul>
|
||||
<p>Your free community account.</p>
|
||||
<ul><li>Games hosted on eom.dev</li><li>Giveaways exclusive to Open Lab members</li></ul>
|
||||
<h4>Included services</h4>
|
||||
<ul class="tier-services">{% for service in free_services %}<li>{{ service }}</li>{% empty %}<li>No additional service access is currently configured.</li>{% endfor %}</ul>
|
||||
{% if not account %}<a class="button button-secondary" href="{% url 'members:register' %}">Join the community</a>{% else %}<p class="tier-footnote">Your free account is ready.</p>{% endif %}
|
||||
</article>
|
||||
{% for key, tier in tiers.items %}
|
||||
<article class="member-panel tier-card">
|
||||
<p class="card-kicker">Level {{ tier.level }} · Independent work, supported together</p><h3>{{ tier.label }}</h3><p class="tier-price">{{ tier.price_label }}</p>
|
||||
<p class="card-kicker">Level {{ tier.level }}</p><h3>{{ tier.label }}</h3><p class="tier-price">{{ tier.price_label }}</p>
|
||||
<p>{{ tier.description|default:"Help keep the projects and community running." }}</p>
|
||||
<ul>{% for benefit in tier.benefits %}<li>{{ benefit }}</li>{% empty %}<li>Support independent projects and the community</li>{% endfor %}</ul>
|
||||
<h4>Included services</h4>
|
||||
@@ -100,8 +100,7 @@
|
||||
<details><summary>How do tier-exclusive giveaways work?</summary><p>Each membership tier, including free Open Lab, has its own exclusive giveaways when announced. Eligibility is based on the tier specified in each giveaway's rules; higher tiers do not automatically qualify for another tier's giveaway. Availability, dates, prizes and eligibility restrictions will be published for each giveaway. Membership does not guarantee a prize.</p></details>
|
||||
<details><summary>Who can vote on the platform's direction?</summary><p>Platinum (Level 4) and Diamond (Level 5) members can take part in exclusive polls about the direction of the platform. These are separate from Gold's project-topic polls. Results help inform decisions; they are not binding commitments or guarantees of particular features.</p></details>
|
||||
<details><summary>What happens when a membership ends?</summary><p>Your free eom.dev account stays. Member-only access ends when your paid membership expires. An immediate cancellation removes that access once your membership status updates.</p></details>
|
||||
<details><summary>Where do members connect?</summary><p>The shared members' Matrix space is the home for informal conversations and work in progress. Private forum discussions can complement it as they become available, without splitting everyone into separate rooms for each tier.</p></details>
|
||||
<details><summary>What can I preview or take part in?</summary><p>Depending on what is being made, Silver members and above may preview music, game builds, videos or new experiments and join playtests or listening sessions. Gold members and above can also take part in project-topic polls and occasional small-group feedback sessions. Polls help inform the work; they are not promises to build requested features.</p></details>
|
||||
<details><summary>Where do members connect?</summary><p>On Discourse and Matrix. Ordinary community access is free; Bronze and above also receive exclusive content in those services.</p></details>
|
||||
<details><summary>Can I change or cancel a plan?</summary><p>Use Manage billing after signing in. The billing portal offers the changes enabled for your plan. Cancellation at period end keeps access through the paid expiry date.</p></details>
|
||||
{% if shkeeper_enabled %}<details><summary>How do crypto memberships renew?</summary><p>SHKeeper payments prepay one calendar month, without automatic charges. Create a new invoice for each renewal. Confirmed payment on the same tier extends its prepaid term. Partial or unconfirmed payments do not grant access. Do not send renewal funds to an old invoice address.</p></details>{% endif %}
|
||||
</section>
|
||||
|
||||
+10
-16
@@ -6,10 +6,9 @@
|
||||
"price_label": "$4 USD / month",
|
||||
"usd_amount": "4.00",
|
||||
"group_dn": "cn=Level 1,ou=Members,dc=eom,dc=dev",
|
||||
"description": "Kick off the experiment with a private place to connect and a closer look at what is being made.",
|
||||
"description": "Go beyond the public feed.",
|
||||
"benefits": [
|
||||
"Exclusive members-only content on Discourse and Matrix",
|
||||
"Behind-the-scenes notes and work-in-progress updates",
|
||||
"Exclusive Discourse and Matrix content, including work-in-progress updates",
|
||||
"Giveaways exclusive to Bronze members",
|
||||
"Optional credit on the community supporters page"
|
||||
]
|
||||
@@ -21,12 +20,11 @@
|
||||
"price_label": "$8 USD / month",
|
||||
"usd_amount": "8.00",
|
||||
"group_dn": "cn=Level 2,ou=Members,dc=eom,dc=dev",
|
||||
"description": "Venture behind the scenes and explore new experiments before their public release.",
|
||||
"description": "Try new work before release.",
|
||||
"benefits": [
|
||||
"Bronze content and community benefits",
|
||||
"Giveaways exclusive to Silver members",
|
||||
"Early previews of music, games, videos and experiments when available",
|
||||
"Invitations to member playtests and listening sessions"
|
||||
"Early previews, playtests and listening sessions when available"
|
||||
]
|
||||
},
|
||||
"level-3": {
|
||||
@@ -36,7 +34,7 @@
|
||||
"price_label": "$16 USD / month",
|
||||
"usd_amount": "16.00",
|
||||
"group_dn": "cn=Level 3,ou=Members,dc=eom,dc=dev",
|
||||
"description": "Bring your perspective and help shape the next community experiment.",
|
||||
"description": "Help shape the next experiment.",
|
||||
"benefits": [
|
||||
"Silver content and community benefits",
|
||||
"Giveaways exclusive to Gold members",
|
||||
@@ -51,13 +49,11 @@
|
||||
"price_label": "$32 USD / month",
|
||||
"usd_amount": "32.00",
|
||||
"group_dn": "cn=Level 4,ou=Members,dc=eom,dc=dev",
|
||||
"description": "Support the platform and help guide its direction through exclusive polls.",
|
||||
"description": "Have a voice in the platform's direction.",
|
||||
"benefits": [
|
||||
"Gold content and community benefits",
|
||||
"Giveaways exclusive to Platinum members",
|
||||
"Exclusive polls on the direction of the platform",
|
||||
"A larger contribution toward servers and public projects",
|
||||
"Choose this level if you would like to give more"
|
||||
"Exclusive platform-direction polls"
|
||||
]
|
||||
},
|
||||
"level-5": {
|
||||
@@ -67,13 +63,11 @@
|
||||
"price_label": "$64 USD / month",
|
||||
"usd_amount": "64.00",
|
||||
"group_dn": "cn=Level 5,ou=Members,dc=eom,dc=dev",
|
||||
"description": "Help underwrite the public work and the community around it.",
|
||||
"description": "Give the independent work its biggest boost.",
|
||||
"benefits": [
|
||||
"Gold content and community benefits",
|
||||
"Platinum content and platform-direction polls",
|
||||
"Giveaways exclusive to Diamond members",
|
||||
"Exclusive polls on the direction of the platform",
|
||||
"Optional Diamond credit on the supporters page",
|
||||
"Your biggest boost for independent public projects"
|
||||
"Optional Diamond credit on the supporters page"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user