Skip to content

Commit cf0b8bd

Browse files
chore(docs): tweak backers/donors (#4807)
* chore(docs): tweak backers/donors * Update contributors-container.js * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors-container.js * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors-container.js * Update contributors-container.js * Update contributors-container.js * Update contributors-container.js * Update contributors.vue * Update contributors-container.js * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors.vue * Update contributors-container.js * Update contributors.vue * Update contributors-container.js * Update contributors.vue * Update contributors-container.js * Update contributors.vue Co-authored-by: Jacob Müller <jacob.mueller.elz@gmail.com>
1 parent 578a06f commit cf0b8bd

File tree

2 files changed

+88
-18
lines changed

2 files changed

+88
-18
lines changed

docs/components/contributors-container.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ export default {
1818
showName: {
1919
type: Boolean,
2020
default: true
21+
},
22+
nofollow: {
23+
type: Boolean,
24+
default: true
2125
}
2226
},
2327
render(h, { props, data }) {
24-
const { type, contributors, showName } = props
28+
const { type, contributors, showName, nofollow } = props
2529

2630
if (contributors.length === 0) {
2731
return h()
@@ -56,14 +60,14 @@ export default {
5660
)
5761

5862
let $name = h()
59-
if (showName) {
63+
if (showName && name) {
6064
$name = h(
6165
'div',
6266
{
6367
staticClass: `${CONTRIBUTOR_CLASS_NAME}-name`,
64-
class: ['small', 'mb-0 ', 'pt-2', 'text-break']
68+
class: ['mb-0', 'pt-2', 'text-break']
6569
},
66-
[name]
70+
name
6771
)
6872
}
6973

@@ -74,7 +78,12 @@ export default {
7478
'b-link',
7579
{
7680
class: ['text-reset'],
77-
props: { href: website, target: '_blank' }
81+
props: {
82+
href: website,
83+
target: '_blank',
84+
// We exclude `nofollow` on sponsor website links
85+
rel: nofollow ? 'noopener nofollow external' : 'noopener external'
86+
}
7887
},
7988
[$content]
8089
)

docs/components/contributors.vue

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<BVDContributorsContainer
1111
type="platinum-sponsors"
1212
:contributors="platinumSponsors"
13+
:nofollow="false"
1314
></BVDContributorsContainer>
1415
</template>
1516

@@ -19,6 +20,7 @@
1920
<BVDContributorsContainer
2021
type="gold-sponsors"
2122
:contributors="goldSponsors"
23+
:nofollow="false"
2224
></BVDContributorsContainer>
2325
</template>
2426

@@ -28,6 +30,7 @@
2830
<BVDContributorsContainer
2931
type="silver-sponsors"
3032
:contributors="silverSponsors"
33+
:nofollow="false"
3134
></BVDContributorsContainer>
3235
</template>
3336

@@ -37,6 +40,7 @@
3740
<BVDContributorsContainer
3841
type="bronze-sponsors"
3942
:contributors="bronzeSponsors"
43+
:nofollow="false"
4044
></BVDContributorsContainer>
4145
</template>
4246
</template>
@@ -71,12 +75,25 @@
7175
height: 55px;
7276
}
7377
78+
a:hover .contributor-thumbnail {
79+
background-color: #6c757d40;
80+
}
81+
82+
.contributor-name {
83+
font-size: 80%;
84+
font-weight: 400;
85+
}
86+
7487
.backers & {
7588
width: 80px;
7689
7790
.contributor-thumbnail {
7891
height: 80px;
7992
}
93+
94+
.contributor-name {
95+
font-size: 70%;
96+
}
8097
}
8198
8299
.bronze-sponsors & {
@@ -93,6 +110,11 @@
93110
.contributor-thumbnail {
94111
height: 100px;
95112
}
113+
114+
.contributor-name {
115+
font-size: 90%;
116+
font-weight: bold;
117+
}
96118
}
97119
98120
.gold-sponsors & {
@@ -101,6 +123,11 @@
101123
.contributor-thumbnail {
102124
height: 120px;
103125
}
126+
127+
.contributor-name {
128+
font-size: 90%;
129+
font-weight: bold;
130+
}
104131
}
105132
106133
.platinum-sponsors & {
@@ -109,6 +136,11 @@
109136
.contributor-thumbnail {
110137
height: 140px;
111138
}
139+
140+
.contributor-name {
141+
font-size: 100%;
142+
font-weight: bold;
143+
}
112144
}
113145
}
114146
</style>
@@ -117,10 +149,17 @@
117149
import BVDContributorsContainer from '~/components/contributors-container'
118150
119151
const OC_BASE_URL = 'https://rest.opencollective.com/v2/bootstrap-vue/orders/'
120-
const OC_DEFAULT_PARAMS = { status: 'active', tierSlug: null, limit: 100 }
152+
const OC_DEFAULT_PARAMS = { status: 'active', tierSlug: null, limit: 200 }
153+
154+
const MAX_BACKERS = 32
155+
const MAX_DONORS = 64
121156
122-
const MAX_BACKERS = 16
123-
const MAX_DONORS = 32
157+
// This value needs to be less than or equal to our bronze tier amount
158+
// We may want to set two thresholds: a single donation amount and
159+
// a total dontation amount. This determine if we link to the donors
160+
// website or not. Used to help prevent abuse of opencollective via
161+
// small dontations to gain cheep backlinks for Google page rank
162+
const LINK_AMT_THRESHOLD = 20
124163
125164
export default {
126165
name: 'BVDContributors',
@@ -179,19 +218,35 @@ export default {
179218
},
180219
processOcNodes(nodes = []) {
181220
return nodes.map(entry => {
221+
// For recurring donations, this is the total amount donated
222+
// For users that donate multiple times, this will be the total of all one time donations
223+
const totalAmount = entry.totalDonations.value
224+
const amount = entry.amount.value
225+
// Fallback URL
226+
const slug = entry.fromAccount.slug
227+
const fallbackUrl = slug ? `https://opencollective.com/${slug}` : null
228+
// Return the normalized result
182229
return {
183-
slug: entry.fromAccount.slug,
230+
slug: slug,
184231
name: entry.fromAccount.name,
232+
// type: 'ORGANIZATION', 'INDIVIDUAL'
185233
type: entry.fromAccount.type,
186234
imageUrl: entry.fromAccount.imageUrl,
187-
website: entry.fromAccount.website,
235+
// We only link their website when the total amount is at or above a certain
236+
// threshold to prevent some questionable websites from abusing opencollective
237+
// as a means to improve thier Google page ranking via backlinks
238+
website:
239+
Math.max(amount || 0, totalAmount || 0) < LINK_AMT_THRESHOLD
240+
? null
241+
: entry.fromAccount.website || fallbackUrl,
242+
// status: 'ACTIVE' = typically recurring, 'PAID' = typially one time donation
188243
status: entry.status,
189244
// For recurring donations, this is the installment amount
190245
// For one time donations, this is the donation amount (most recent)
191-
amount: entry.amount.value,
246+
amount: amount,
192247
// For recurring donations, this is the total amount donated
193248
// For users that donate multiple times, this will be the total of all one time donations
194-
totalAmount: entry.totalDonations.value,
249+
totalAmount: totalAmount,
195250
// For recurring donations, this is how often the donation is received
196251
frequency: entry.frequency,
197252
// We now have sponsor tiers, but some appear as
@@ -228,15 +283,20 @@ export default {
228283
processBackers(backers = []) {
229284
// Backers are provided in reverse chronological order
230285
// so we sort by larger amount first, then by date
231-
// Limit to top 16 backers
232-
this.backers = backers.sort(this.sortCompare).slice(0, MAX_BACKERS)
286+
// Some backers have the tier level as `null`, which started
287+
// backing before we started the tier levels
288+
// Limit to top N backers
289+
this.backers = backers
290+
.filter(b => b.tier === null || b.tier === 'backers')
291+
.sort(this.sortCompare)
292+
.slice(0, MAX_BACKERS)
233293
},
234294
processDonors(donors = []) {
235295
// Donors are provided in reverse chronological order,
236296
// but donors can be listed more than once (for each individual donation),
237-
// although the `totalDonations` is the same on each entry
238-
// We sort by larger amount first, then by date
239-
// Limit to top 32 most recent donors
297+
// although the `totalDonations` is the same on each entry. We filter out
298+
// duplicate donors by slug, then sort by larger amount first, then by date
299+
// Limit to top N most recent donors
240300
this.donors = donors
241301
.reduce((results, donor) => {
242302
if (results.map(d => d.slug).indexOf(donor.slug) === -1) {
@@ -260,7 +320,8 @@ export default {
260320
// Bronze sponors are people/organizations with a recurring (active) bronze sponorship
261321
this.makeOcRequest(this.processBronzeSponsors.bind(this), { tierSlug: 'bronze-sponsors' })
262322
// Backers are people/organizations with recurring (active) donations
263-
this.makeOcRequest(this.processBackers.bind(this), { tierSlug: 'backers' })
323+
// Some backers are not tagged as "backers" slug (`null` slug), but have status "active"
324+
this.makeOcRequest(this.processBackers.bind(this), { status: 'active' })
264325
// Donors are people/organizations with one-time (paid) donations
265326
this.makeOcRequest(this.processDonors.bind(this), { status: 'paid' })
266327
}

0 commit comments

Comments
 (0)