mirror of
https://github.com/LBRYFoundation/lbry.com.git
synced 2025-08-23 09:37:26 +00:00
bounty program 1.0
This commit is contained in:
parent
369d72a9f5
commit
7bab13881d
14 changed files with 187 additions and 86 deletions
|
@ -6,16 +6,18 @@ class BountyActions extends Actions
|
|||
|
||||
public static function executeList()
|
||||
{
|
||||
$allBounties = Post::find(ROOT_DIR . '/posts/bounty');
|
||||
|
||||
$allCategories = ['' => ''] + Post::collectMetadata($allBounties, 'category');
|
||||
$allStatuses = ['' => ''] + Post::collectMetadata($allBounties, 'status');
|
||||
|
||||
$selectedStatus = static::param('status');
|
||||
$selectedCategory = static::param('category');
|
||||
|
||||
$filters = array_filter(['category' => $selectedCategory, 'status' => $selectedStatus]);
|
||||
$allBounties = Post::find(ROOT_DIR . '/posts/bounty');
|
||||
|
||||
$allCategories = array_unique(array_map(function(Post $post) {
|
||||
$metadata = $post->getMetadata();
|
||||
return isset($metadata['category']) ? $metadata['category'] : null;
|
||||
}, $allBounties));
|
||||
$filters = array_filter([
|
||||
'category' => $selectedCategory && isset($allCategories[$selectedCategory]) ? $selectedCategory : null,
|
||||
'status' => $selectedStatus && isset($allStatuses[$selectedStatus]) ? $selectedStatus : null
|
||||
]);
|
||||
|
||||
$bounties = $filters ? Post::filter($allBounties, $filters) : $allBounties;
|
||||
|
||||
|
@ -32,6 +34,7 @@ class BountyActions extends Actions
|
|||
return ['bounty/list', [
|
||||
'bounties' => $bounties,
|
||||
'categories' => $allCategories,
|
||||
'statuses' => $allStatuses,
|
||||
'selectedCategory' => $selectedCategory,
|
||||
'selectedStatus' => $selectedStatus
|
||||
]];
|
||||
|
|
|
@ -23,9 +23,9 @@ class ContentActions extends Actions
|
|||
|
||||
public static function executeFaq()
|
||||
{
|
||||
$posts = Post::find(static::VIEW_FOLDER_FAQ);
|
||||
$allPosts = Post::find(static::VIEW_FOLDER_FAQ);
|
||||
|
||||
$groupNames = [
|
||||
$allCategories = array_merge(['' => ''] + Post::collectMetadata($allPosts, 'category'), [
|
||||
'getstarted' => 'Getting Started',
|
||||
'install' => 'Installing LBRY',
|
||||
'running' => 'Running LBRY',
|
||||
|
@ -35,17 +35,27 @@ class ContentActions extends Actions
|
|||
'policy' => 'Policies',
|
||||
'developer' => 'Developers',
|
||||
'other' => 'Other Questions',
|
||||
];
|
||||
]);
|
||||
$selectedCategory = static::param('category');
|
||||
$filters = array_filter([
|
||||
'category' => $selectedCategory && isset($allCategories[$selectedCategory]) ? $selectedCategory : null,
|
||||
]);
|
||||
|
||||
$groups = array_fill_keys(array_keys($groupNames), []);
|
||||
asort($allCategories);
|
||||
|
||||
$posts = $filters ? Post::filter($allPosts, $filters) : $allPosts ;
|
||||
|
||||
|
||||
$groups = array_fill_keys(array_keys($allCategories), []);
|
||||
|
||||
foreach($posts as $post)
|
||||
{
|
||||
$groups[isset($groupNames[$post->getCategory()]) ? $post->getCategory() : 'other'][] = $post;
|
||||
$groups[$post->getCategory()][] = $post;
|
||||
}
|
||||
|
||||
return ['content/faq', [
|
||||
'groupNames' => $groupNames,
|
||||
'categories' => $allCategories,
|
||||
'selectedCategory' => $selectedCategory,
|
||||
'postGroups' => $groups
|
||||
]];
|
||||
}
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
#
|
||||
#
|
||||
|
||||
bounty:
|
||||
list:
|
||||
noresult: No matching bounties found.
|
||||
show:
|
||||
completednotice: This bounty has already been completed and can no longer be claimed.
|
||||
description:
|
||||
allowed: Download/install the latest version of LBRY for %os%.
|
||||
faq: Frequently asked questions about LBRY.
|
||||
|
|
|
@ -343,6 +343,16 @@ class Post
|
|||
return strtolower(preg_replace('#^\d+\-#', '', basename(trim($filename), '.md')));
|
||||
}
|
||||
|
||||
public static function collectMetadata(array $posts, $field)
|
||||
{
|
||||
$values = array_unique(array_map(function(Post $post) use($field) {
|
||||
$metadata = $post->getMetadata();
|
||||
return isset($metadata[$field]) ? $metadata[$field] : null;
|
||||
}, $posts));
|
||||
sort($values);
|
||||
return array_combine($values, $values);
|
||||
}
|
||||
|
||||
public static function getSlugMap($postType)
|
||||
{
|
||||
if (!isset(static::$slugMap[$postType]))
|
||||
|
|
26
posts/faq/bounties.md
Normal file
26
posts/faq/bounties.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
title: How does the Bounty Program work?
|
||||
category: policy
|
||||
---
|
||||
|
||||
You can earn LBRY Credits for completing tasks as part of the LBRY Bounty Program.
|
||||
|
||||
### What bounties are available?
|
||||
|
||||
All bounties can be seen on the [bounty home page](/bounty).
|
||||
|
||||
### How do I claim a bounty?
|
||||
|
||||
To claim a bounty, please email [bounty@lbry.io](mailto:bounty@lbry.io). Please include a link to the bounty. If it is programming related, please include a link to the pull request.
|
||||
|
||||
### How do I get compensated?
|
||||
|
||||
People who complete bounties are awarded LBRY credits. These credits will be transferred to a wallet address of your choice and are yours with no restrictions to do as you like.
|
||||
|
||||
### I have questions about a specific bounty or want assistance in completing a bounty.
|
||||
|
||||
The best place to get real-time help is our [Slack channel](https://slack.lbry.io). You can also email our bounty team [bounty@lbry.io](mailto:bounty@lbry.io).
|
||||
|
||||
### I want to complete a bounty that is not listed.
|
||||
|
||||
Send an email our bounty team at [bounty@lbry.io](mailto:bounty@lbry.io).
|
4
view/template/bounty/_meta.php
Normal file
4
view/template/bounty/_meta.php
Normal file
|
@ -0,0 +1,4 @@
|
|||
<div class="clearfix">
|
||||
<span class="align-left"><span class="meta"><?php echo $metadata['category'] ?></span></span>
|
||||
<span class="align-right"><span class="badge badge-primary bounty-award"><?php echo i18n::formatCredits($metadata['award']) ?></span></span>
|
||||
</div>
|
|
@ -2,7 +2,7 @@
|
|||
<?php NavActions::setNavUri('/learn') ?>
|
||||
<?php echo View::render('nav/_header', ['isDark' => false]) ?>
|
||||
<main>
|
||||
<div class="hero hero-quote hero-img spacer2" style="background-image: url(/img/fireworks.png)">
|
||||
<div class="hero hero-quote hero-img hero-img-short spacer1" style="background-image: url(/img/fireworks.png)">
|
||||
<div class="hero-content-wrapper">
|
||||
<div class="hero-content text-center">
|
||||
<h1 class="cover-title">LBRY Bounties</h1>
|
||||
|
@ -12,23 +12,22 @@
|
|||
</div>
|
||||
<section class="content content-light">
|
||||
<h3>Bounties</h3>
|
||||
<p>Complete challenges and earn LBRY Credits. <a class="link-primary" href="/faq/bounties">Learn more</a>.</p>
|
||||
<form method="get" action="/bounty" id="bounty-filter-form">
|
||||
<div class="clearfix">
|
||||
<div class="form-row align-left" style="margin-right: 10px">
|
||||
<label>Category</label>
|
||||
<select name="category">
|
||||
<?php foreach($categories as $category): ?>
|
||||
<option value="<?php echo $category ?>" <?php echo $selectedCategory == $category ? 'selected="selected"' : '' ?>>
|
||||
<?php echo $category ?>
|
||||
</option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
<?php echo View::render('form/_select', [
|
||||
'name' => 'category',
|
||||
'choices' => $categories,
|
||||
'selected' => $selectedCategory
|
||||
]) ?>
|
||||
</div>
|
||||
<div class="form-row align-left">
|
||||
<label>Completed</label>
|
||||
<select name="status">
|
||||
<?php foreach(['' => 'any', 'available' => 'available', 'completed' => 'completed'] as $statusVal => $statusLabel): ?>
|
||||
<option value="<?php echo $statusVal ?>"><?php echo $statusLabel ?></option>
|
||||
<?php foreach($statuses as $statusVal => $statusLabel): ?>
|
||||
<option value="<?php echo $statusVal ?>" <?php echo $selectedStatus == $statusVal ? 'selected="selected"' : '' ?>><?php echo $statusLabel ?></option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -39,31 +38,31 @@
|
|||
<?php js_end() ?>
|
||||
</section>
|
||||
<section class="content content-light">
|
||||
<div class="tile-fluid clearfix spacer2">
|
||||
<?php foreach($bounties as $post): ?>
|
||||
<div class="span4">
|
||||
<a class="bounty-tile" href="<?php echo $post->getRelativeUrl() ?>">
|
||||
<div class="text-center spacer-half"><span class="icon-mega
|
||||
<?php $metadata = $post->getMetadata() ?>
|
||||
<?php switch($metadata['category']) {
|
||||
case 'ci': echo 'icon-wrench'; break;
|
||||
case 'android': echo 'icon-android'; break;
|
||||
case 'ios': echo 'icon-apple'; break;
|
||||
case 'browser': echo 'icon-globe'; break;
|
||||
case 'cif': echo 'icon-wrench'; break;
|
||||
case 'cig': echo 'icon-wrench'; break;
|
||||
default: echo 'icon-dollar'; break;
|
||||
} ?>
|
||||
"></span></div>
|
||||
<h3 class="link-primary"><?php echo $post->getTitle() ?></h3>
|
||||
<div class="clearfix">
|
||||
<span class="align-left"><span class="meta"><?php echo $metadata['category'] ?></span></span>
|
||||
<span class="align-right"><span class="badge badge-primary"><?php echo i18n::formatCredits($metadata['award']) ?></span></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?php if (count($bounties)): ?>
|
||||
<div class="tile-fluid clearfix spacer2">
|
||||
<?php foreach($bounties as $post): ?>
|
||||
<?php $metadata = $post->getMetadata() ?>
|
||||
<div class="span4">
|
||||
<a class="bounty-tile <?php echo isset($metadata['status']) ? 'bounty-status-' . $metadata['status'] : '' ?>" href="<?php echo $post->getRelativeUrl() ?>">
|
||||
<div class="text-center spacer-half"><span class="icon-mega
|
||||
<?php switch($metadata['category']) {
|
||||
case 'ci': echo 'icon-wrench'; break;
|
||||
case 'android': echo 'icon-android'; break;
|
||||
case 'ios': echo 'icon-apple'; break;
|
||||
case 'browser': echo 'icon-globe'; break;
|
||||
case 'human': echo 'icon-users'; break;
|
||||
default: echo 'icon-dollar'; break;
|
||||
} ?>
|
||||
"></span></div>
|
||||
<h3 class="link-primary"><?php echo $post->getTitle() ?></h3>
|
||||
<?php echo View::render('bounty/_meta', ['metadata' => $metadata]) ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<p><em>{{bounty.list.noresults}}</em></p>
|
||||
<?php endif ?>
|
||||
</section>
|
||||
</main>
|
||||
<?php echo View::render('nav/_footer') ?>
|
||||
|
|
|
@ -2,15 +2,31 @@
|
|||
<?php NavActions::setNavUri('/learn') ?>
|
||||
<?php echo View::render('nav/_header') ?>
|
||||
<main>
|
||||
<section class="post-content">
|
||||
<div class="content">
|
||||
<div class="meta">
|
||||
<br/>
|
||||
<a href="/bounty">« Back to All Bounties</a>
|
||||
</div>
|
||||
<h1><?php echo htmlentities($metadata['title']) ?></h1>
|
||||
<?php echo $postHtml ?>
|
||||
<div class="post-content">
|
||||
<div class="meta">
|
||||
<br/>
|
||||
<a href="/bounty" class="link-primary">« Back to All Bounties</a>
|
||||
</div>
|
||||
</section>
|
||||
<section class="spacer2">
|
||||
<h1><?php echo htmlentities($metadata['title']) ?></h1>
|
||||
<div class="spacer1">
|
||||
<?php echo View::render('bounty/_meta', ['metadata' => $metadata]) ?>
|
||||
</div>
|
||||
<?php if ($metadata['status'] == 'complete'): ?>
|
||||
<div class="notice notice-info spacer1">{{bounty.show.completednotice}}</div>
|
||||
<?php endif ?>
|
||||
<?php echo $postHtml ?>
|
||||
</section>
|
||||
<section>
|
||||
<h4>Claim This Bounty</h4>
|
||||
<div class="spacer1">
|
||||
<a href="mailto:bounty@lbry.io?subject=<?php echo $metadata['title'] ?>" class="btn btn-alt">Claim Bounty</a>
|
||||
</div>
|
||||
<h4>Bounty Questions?</h4>
|
||||
<div class="spacer1">
|
||||
<a href="/faq/bounties">Read the FAQ</a>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
<?php echo View::render('nav/_footer', ['showLearnFooter' => true]) ?>
|
||||
|
|
|
@ -4,13 +4,29 @@
|
|||
<main>
|
||||
<section class="content content-readable spacer2">
|
||||
<h1>{{page.faq.header}}</h1>
|
||||
<?php foreach($postGroups as $group => $posts): ?>
|
||||
<h2><?php echo $groupNames[$group] ?></h2>
|
||||
<?php foreach($posts as $post): ?>
|
||||
<div class="spacer1">
|
||||
<a href="<?php echo $post->getRelativeUrl() ?>" class="link-primary"><?php echo $post->getTitle() ?></a>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
<form method="get" action="/faq" id="faq-filter-form">
|
||||
<div class="form-row">
|
||||
<label>Category</label>
|
||||
<?php echo View::render('form/_select', [
|
||||
'name' => 'category',
|
||||
'choices' => $categories,
|
||||
'selected' => $selectedCategory
|
||||
]) ?>
|
||||
</div>
|
||||
</form>
|
||||
<?php js_start() ?>
|
||||
$('#faq-filter-form').change(function() { $(this).submit(); });
|
||||
<?php js_end() ?>
|
||||
|
||||
<?php foreach($postGroups as $category => $posts): ?>
|
||||
<?php if (count($posts)): ?>
|
||||
<h2><?php echo $categories[$category] ?></h2>
|
||||
<?php foreach($posts as $post): ?>
|
||||
<div class="spacer1">
|
||||
<a href="<?php echo $post->getRelativeUrl() ?>" class="link-primary"><?php echo $post->getTitle() ?></a>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
</section>
|
||||
</main>
|
||||
|
|
7
view/template/form/_select.php
Normal file
7
view/template/form/_select.php
Normal file
|
@ -0,0 +1,7 @@
|
|||
<select name="<?php echo $name ?>">
|
||||
<?php foreach($choices as $value => $label): ?>
|
||||
<option value="<?php echo $value ?>" <?php echo $selected == $value ? 'selected="selected"' : '' ?>>
|
||||
<?php echo $label ?>
|
||||
</option>
|
||||
<?php endforeach ?>
|
||||
</select>
|
|
@ -4,18 +4,20 @@
|
|||
<?php if ($showLearnFooter): ?>
|
||||
<?php echo View::render('nav/_learnFooter', ['isDark' => $isDark]) ?>
|
||||
<?php endif ?>
|
||||
<div class="content footer-standard">
|
||||
<nav class="control-group">
|
||||
<div class="control-item">
|
||||
<a href="/"><?php echo __('nav.home') ?></a>
|
||||
</div>
|
||||
<?php echo View::render('nav/_globalItems') ?>
|
||||
<div class="control-item">
|
||||
<a href="//en.wikipedia.org/wiki/AACS_encryption_key_controversy" class="footer-img-link">
|
||||
<img src="/img/Free-speech-flag.svg" alt="Free Speech Flag" height="30"/>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="footer-standard">
|
||||
<div class="content">
|
||||
<nav class="control-group">
|
||||
<div class="control-item">
|
||||
<a href="/"><?php echo __('nav.home') ?></a>
|
||||
</div>
|
||||
<?php echo View::render('nav/_globalItems') ?>
|
||||
<div class="control-item">
|
||||
<a href="//en.wikipedia.org/wiki/AACS_encryption_key_controversy" class="footer-img-link">
|
||||
<img src="/img/Free-speech-flag.svg" alt="Free Speech Flag" height="30"/>
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
|
|
@ -97,7 +97,7 @@
|
|||
margin-right: auto;
|
||||
max-width: $max-post-content-width;
|
||||
margin-bottom: $spacing-vertical * 2;
|
||||
a[href]
|
||||
a[href]:not([class])
|
||||
{
|
||||
@include anchor($color-primary);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
.bounty-tile
|
||||
{
|
||||
.bounty-tile {
|
||||
display: block;
|
||||
margin: 0 10px $spacing-vertical;
|
||||
padding: 10px;
|
||||
background: #eee;
|
||||
&:hover
|
||||
{
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-mega
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
.bounty-status-complete .bounty-award
|
||||
{
|
||||
text-decoration: line-through;
|
||||
}
|
|
@ -59,6 +59,10 @@
|
|||
background: black url(/img/dark.png) no-repeat top center fixed;
|
||||
min-height: 420px;
|
||||
@include background-size(cover);
|
||||
&.hero-img-short
|
||||
{
|
||||
min-height: 200px;
|
||||
}
|
||||
&:before
|
||||
{
|
||||
position: absolute;
|
||||
|
@ -69,7 +73,7 @@
|
|||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.hero-quote
|
||||
{
|
||||
|
@ -96,7 +100,7 @@
|
|||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
@media (max-width: $mobile-width-threshold)
|
||||
@media (max-width: $mobile-width-threshold)
|
||||
{
|
||||
.hero
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue