Binary file not shown.
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 72 KiB |
BIN
assets/images/help/sponsors/draft-tier-edit.png
Normal file
BIN
assets/images/help/sponsors/draft-tier-edit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/images/help/sponsors/recommended-rewards.png
Normal file
BIN
assets/images/help/sponsors/recommended-rewards.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
BIN
assets/images/help/sponsors/tier-editor-button.png
Normal file
BIN
assets/images/help/sponsors/tier-editor-button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -23,6 +23,12 @@ topics:
|
||||
|
||||
{% data reusables.sponsors.navigate-to-sponsors-dashboard %}
|
||||
{% data reusables.sponsors.navigate-to-sponsor-tiers-tab %}
|
||||
1. If you are setting up tiers for the first time, we recommend you review the suggested tier examples to see how some other open source contributors have set up {% data variables.product.prodname_sponsors %}. Decide whether you want to start with some suggested draft tiers, which you can customize in the tier editor.
|
||||
- To use a suggested tier, select the rewards you'd like to include in your draft tier or tiers. Then, click **Continue to tier editor**.
|
||||
- To create tiers without using with any of the draft suggestions, click **Skip this step**.
|
||||

|
||||
1. Optionally, to edit a draft tier, find the draft tier and click **Edit**.
|
||||

|
||||
{% data reusables.sponsors.click-add-tier %}
|
||||
{% data reusables.sponsors.tier-price-description %}
|
||||
{% data reusables.sponsors.save-tier-draft %}
|
||||
@@ -33,6 +39,11 @@ topics:
|
||||
{% data reusables.sponsors.navigate-to-sponsors-dashboard %}
|
||||
{% data reusables.sponsors.navigate-to-sponsor-tiers-tab %}
|
||||
{% data reusables.sponsors.edit-tier %}
|
||||
{% note %}
|
||||
|
||||
**Note:** To see ideas of tier descriptions, scroll down.
|
||||
|
||||
{% endnote %}
|
||||
{% data reusables.sponsors.tier-price-description %}
|
||||
{% data reusables.sponsors.tier-update %}
|
||||
{% data reusables.sponsors.retire-tier %}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
1. In the upper-right corner of any page, click your profile photo, then click **{% data variables.product.prodname_sponsors %}**.
|
||||
1. In the upper-right corner of any page, click your profile photo, then click **Your sponsors**.
|
||||

|
||||
2. If a list of your sponsored and eligible accounts is shown, to the right of the account you want to manage, click **Dashboard**.
|
||||

|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
You can create up to ten sponsorship tiers for sponsors to choose from. Each tier has its own monthly or one-time payment amount in US dollars and benefits, such as receiving early access to new versions or being featured in the project's README. In addition, you can choose to enable tiers for custom amounts (monthly and one-time).
|
||||
You can create up to 10 one-time sponsorship tiers and 10 monthly tiers for sponsors to choose from. Each tier has its own one-time or monthly payment amount in US dollars, and you can choose to enable tiers for custom amounts. In addition, you can choose to enable tiers for custom amounts (monthly and one-time).
|
||||
|
||||
Once you have published a tier, you can't edit the price of that tier. Instead, you must retire the tier and create a new tier. Existing sponsors will remain on the retired tier until they change their sponsorship tier, cancel their sponsorship, or their one-time sponsorship period expires.
|
||||
You can customize the rewards for each tier. For example, rewards for a tier could include:
|
||||
- Early access to new versions
|
||||
- Logo or name in README
|
||||
- Access to a private repository
|
||||
- Weekly newsletter updates
|
||||
- Other rewards your sponsors would enjoy ✨
|
||||
|
||||
Once you have published a tier, you cannot edit the price of that tier. Instead, you must retire the tier and create a new tier. Existing sponsors will remain on the retired tier until they change their sponsorship tier, cancel their sponsorship, or their one-time sponsorship period expires.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
import { sendEvent } from './events'
|
||||
|
||||
const supportedTools = ['cli', 'desktop', 'webui']
|
||||
const detectedTools = new Set()
|
||||
|
||||
@@ -18,6 +22,16 @@ export default function displayToolSpecificContent () {
|
||||
event.preventDefault()
|
||||
showContentForTool(event.target.dataset.tool)
|
||||
findToolSpecificContent(event.target.dataset.tool)
|
||||
|
||||
// Save this preference as a cookie.
|
||||
Cookies.set('toolPreferred', event.target.dataset.tool, { sameSite: 'strict', secure: true })
|
||||
|
||||
// Send event data
|
||||
sendEvent({
|
||||
type: 'preference',
|
||||
preference_name: 'application',
|
||||
preference_value: event.target.dataset.tool
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -73,6 +87,8 @@ function detectTools (el) {
|
||||
}
|
||||
|
||||
function getDefaultTool () {
|
||||
const cookieValue = Cookies.get('toolPreferred')
|
||||
if (cookieValue) return cookieValue
|
||||
const el = document.querySelector('[data-default-tool]')
|
||||
if (el) return el.dataset.defaultTool
|
||||
}
|
||||
|
||||
@@ -46,12 +46,14 @@ export function sendEvent ({
|
||||
experiment_name,
|
||||
experiment_variation,
|
||||
experiment_success,
|
||||
clipboard_operation
|
||||
clipboard_operation,
|
||||
preference_name,
|
||||
preference_value
|
||||
}) {
|
||||
const body = {
|
||||
_csrf: getCsrf(),
|
||||
|
||||
type, // One of page, exit, link, search, navigate, survey, experiment
|
||||
type, // One of page, exit, link, search, navigate, survey, experiment, preference
|
||||
|
||||
context: {
|
||||
// Primitives
|
||||
@@ -77,7 +79,10 @@ export function sendEvent ({
|
||||
|
||||
// Location information
|
||||
timezone: new Date().getTimezoneOffset() / -60,
|
||||
user_language: navigator.language
|
||||
user_language: navigator.language,
|
||||
|
||||
// Preference information
|
||||
application_preference: Cookies.get('toolPreferred')
|
||||
},
|
||||
|
||||
// Page event
|
||||
@@ -112,7 +117,11 @@ export function sendEvent ({
|
||||
experiment_success,
|
||||
|
||||
// Clipboard event
|
||||
clipboard_operation
|
||||
clipboard_operation,
|
||||
|
||||
// Preference event
|
||||
preference_name,
|
||||
preference_value
|
||||
}
|
||||
const blob = new Blob([JSON.stringify(body)], { type: 'application/json' })
|
||||
navigator.sendBeacon('/events', blob)
|
||||
@@ -230,4 +239,5 @@ export default function initializeEvents () {
|
||||
// experiment event in ./experiment.js
|
||||
// search event in ./search.js
|
||||
// redirect event in middleware/record-redirect.js
|
||||
// preference event in ./display-tool-specific-content.js
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ const SCHEMAS = {
|
||||
experiment: 'docs.v0.ExperimentEvent',
|
||||
redirect: 'docs.v0.RedirectEvent',
|
||||
clipboard: 'docs.v0.ClipboardEvent',
|
||||
print: 'docs.v0.PrintEvent'
|
||||
print: 'docs.v0.PrintEvent',
|
||||
preference: 'docs.v0.PreferenceEvent'
|
||||
}
|
||||
|
||||
module.exports = class Hydro {
|
||||
|
||||
@@ -109,7 +109,22 @@ const context = {
|
||||
user_language: {
|
||||
type: 'string',
|
||||
description: 'The browser value of `navigator.language`.'
|
||||
},
|
||||
|
||||
// Preference information
|
||||
/* os_preference: {
|
||||
type: 'string',
|
||||
description: 'The os for examples selected by the user.'
|
||||
}, */
|
||||
application_preference: {
|
||||
type: 'string',
|
||||
enum: ['webui', 'cli', 'desktop'],
|
||||
description: 'The application selected by the user.'
|
||||
}
|
||||
/* color_mode_preference: {
|
||||
type: 'string',
|
||||
description: 'The color mode selected by the user.'
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,6 +391,34 @@ const printSchema = {
|
||||
}
|
||||
}
|
||||
|
||||
const preferenceSchema = {
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: [
|
||||
'type',
|
||||
'context',
|
||||
'preference_name',
|
||||
'preference_value'
|
||||
],
|
||||
properties: {
|
||||
context,
|
||||
type: {
|
||||
type: 'string',
|
||||
pattern: '^preference$'
|
||||
},
|
||||
preference_name: {
|
||||
type: 'string',
|
||||
enum: ['application'], // os, color_mode
|
||||
description: 'The preference name, such as os, application, or color_mode'
|
||||
},
|
||||
preference_value: {
|
||||
type: 'string',
|
||||
enum: ['webui', 'cli', 'desktop'],
|
||||
description: 'The application selected by the user.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
oneOf: [
|
||||
pageSchema,
|
||||
@@ -387,6 +430,7 @@ module.exports = {
|
||||
experimentSchema,
|
||||
redirectSchema,
|
||||
clipboardSchema,
|
||||
printSchema
|
||||
printSchema,
|
||||
preferenceSchema
|
||||
]
|
||||
}
|
||||
|
||||
@@ -474,4 +474,25 @@ describe('POST /events', () => {
|
||||
checkEvent(printExample, 200)
|
||||
)
|
||||
})
|
||||
|
||||
describe('preference', () => {
|
||||
const preferenceExample = {
|
||||
...baseExample,
|
||||
type: 'preference',
|
||||
preference_name: 'application',
|
||||
preference_value: 'cli'
|
||||
}
|
||||
|
||||
it('should record an application event', () =>
|
||||
checkEvent(preferenceExample, 200)
|
||||
)
|
||||
|
||||
it('preference_name is string', () => {
|
||||
checkEvent({ ...preferenceExample, preference_name: null }, 400)
|
||||
})
|
||||
|
||||
it('preference_value is string', () => {
|
||||
checkEvent({ ...preferenceExample, preference_value: null }, 400)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user