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
2 changes: 2 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ko_fi: vpdaspid
custom: ["https://assetstore.unity.com/packages/package/2333465"]
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,5 @@ Requires Unity 6000.0.53f1 or newer. If you got the package from the Asset Store

## Support the project

<a href="https://assetstore.unity.com/packages/package/2333465"><img src="Website/docs/Images/support-card.svg" alt="Aspid.FastTools is developed in spare time. If it helps you, support its development on the Unity Asset Store." width="100%"></a>
<a href="https://ko-fi.com/vpdaspid"><img src="Website/docs/Images/support-card.svg" alt="Aspid.FastTools is developed in spare time. If it helps you, support its development on Ko-fi or the Unity Asset Store." width="100%"></a>
<p><a href="https://ko-fi.com/vpdaspid"><img src="Website/docs/Images/support-kofi.svg" alt="Support on Ko-fi" height="48"></a>&nbsp;&nbsp;<a href="https://assetstore.unity.com/packages/package/2333465"><img src="Website/docs/Images/support-store.svg" alt="Unity Asset Store" height="48"></a></p>
14 changes: 4 additions & 10 deletions Website/docs/Images/support-card.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions Website/docs/Images/support-kofi.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions Website/docs/Images/support-store.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Website/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,4 @@ Distributed under the [MIT License](https://github.com/VPDPersonal/Aspid.FastToo

## Support the project

Aspid.FastTools is developed in spare time. If it helps you, support its development on the [Unity Asset Store](https://assetstore.unity.com/packages/package/2333465).
Aspid.FastTools is developed in spare time. If it helps you, support its development on [Ko-fi](https://ko-fi.com/vpdaspid) or the [Unity Asset Store](https://assetstore.unity.com/packages/package/2333465).
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,4 @@ caster.GetDisplayNameWithIndex();

## Поддержать проект

Aspid.FastTools развивается в свободное время. Если пакет вам помогает, поддержите его развитие в [Unity Asset Store](https://assetstore.unity.com/packages/package/2333465).
Aspid.FastTools развивается в свободное время. Если пакет вам помогает, поддержите его развитие на [Ko-fi](https://ko-fi.com/vpdaspid) или в [Unity Asset Store](https://assetstore.unity.com/packages/package/2333465).
27 changes: 19 additions & 8 deletions Website/scripts/github-readme.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
* a code preview gives way to the recording of the site's animated preview (`Website/docs/Images/readme-previews`);
* - a section that is only a list of `[Link](…) — summary` items becomes a row of link tiles;
* - the help section becomes the site's call to action (src/components/SupportPanel), without the licence line;
* - the donation sentence gives way to the image of the site's donation card (src/components/DonatePanel), linking
* the Asset Store (`Website/docs/Images/support-card.svg`); the sentence becomes its alt text.
* - the donation sentence gives way to the image of the site's donation card (src/components/DonatePanel) and a row
* of button images under it, one per place: Ko-fi and the Asset Store (`Website/docs/Images/support-*.svg`); the
* sentence becomes the card's alt text.
* The README shows only the dark images: a <picture> per theme follows the system theme, not GitHub's, so it showed the
* light ones on a dark GitHub page.
* All file URLs are already relative to the README.
Expand Down Expand Up @@ -194,20 +195,30 @@ function supportPanel(tree, repository) {
}

/**
* The donation section: one sentence linking the Asset Store. GitHub cannot style a card, so the sentence gives way to
* an image of the site's one, linking the store.
* The donation section: one sentence linking Ko-fi and the Asset Store. GitHub cannot style a card, and an image links
* one place, so the sentence gives way to an image of the site's card, linking the first place, and a row of button
* images under it, one per place.
*/
function donateCard(tree, {images, exists}) {
const isStore = (url) => /^https:\/\/assetstore\.unity\.com\//.test(url);
const places = [
{test: (url) => /^https:\/\/ko-fi\.com\//.test(url), button: `${images}/support-kofi.svg`, alt: 'Support on Ko-fi'},
{test: (url) => /^https:\/\/assetstore\.unity\.com\//.test(url), button: `${images}/support-store.svg`, alt: 'Unity Asset Store'},
];
const card = `${images}/support-card.svg`;
const index = tree.children.findIndex((node, at) => isHeading(node, 2) && tree.children[at + 1]?.type === 'paragraph'
&& tree.children[at + 1].children.some((part) => part.type === 'link' && isStore(part.url))
&& tree.children[at + 1].children.some((part) => part.type === 'link' && places.some(({test}) => test(part.url)))
&& (!tree.children[at + 2] || tree.children[at + 2].type === 'heading'));
if (index === -1 || !exists(card)) return;
const sentence = tree.children[index + 1].children;
const store = escape(sentence.find((part) => part.type === 'link' && isStore(part.url)).url);
const links = places.flatMap((place) => {
const link = sentence.find((part) => part.type === 'link' && place.test(part.url));
return link ? [{...place, url: escape(link.url)}] : [];
});
const alt = escape(sentence.map(function text(part) { return part.value ?? part.children?.map(text).join('') ?? ''; }).join(''));
tree.children[index + 1] = html(`<a href="${store}">${image(card, alt, ' width="100%"')}</a>`);
const buttons = links.filter(({button}) => exists(button))
.map(({url, button, alt: label}) => `<a href="${url}">${image(button, label, ' height="48"')}</a>`);
tree.children[index + 1] = html(`<a href="${links[0].url}">${image(card, alt, ' width="100%"')}</a>`
+ (buttons.length ? `\n<p>${buttons.join('&nbsp;&nbsp;')}</p>` : ''));
}


Expand Down
18 changes: 14 additions & 4 deletions Website/scripts/github-readme.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,24 @@ test('the help section becomes the call to action, without the licence line', ()
+ '<p><a href="https://github.com/owner/repo/issues"><b>Open an issue</b></a> · <a href="https://github.com/owner/repo">Star on GitHub</a></p>\n');
});

test('the donation sentence gives way to the card image, the sentence its alt text', () => {
test('the donation sentence gives way to the card image and a button per place, the sentence the card alt text', () => {
const kofi = 'https://ko-fi.com/owner';
const store = 'https://assetstore.unity.com/packages/package/1';
const section = `## Support\n\nSupport it on the [Asset Store](${store}).\n`;
assert.equal(layout(section, ['Website/docs/Images/support-card.svg']), '## Support\n\n'
+ `<a href="${store}"><img src="Website/docs/Images/support-card.svg" alt="Support it on the Asset Store." width="100%"></a>\n`);
const images = ['support-card.svg', 'support-kofi.svg', 'support-store.svg'].map((name) => `Website/docs/Images/${name}`);
const section = `## Support\n\nSupport it on [Ko-fi](${kofi}) or the [Asset Store](${store}).\n`;
assert.equal(layout(section, images), '## Support\n\n'
+ `<a href="${kofi}"><img src="Website/docs/Images/support-card.svg" alt="Support it on Ko-fi or the Asset Store." width="100%"></a>\n`
+ `<p><a href="${kofi}"><img src="Website/docs/Images/support-kofi.svg" alt="Support on Ko-fi" height="48"></a>&nbsp;&nbsp;`
+ `<a href="${store}"><img src="Website/docs/Images/support-store.svg" alt="Unity Asset Store" height="48"></a></p>\n`);
assert.equal(layout(section), section, 'without the card image the section stays as it is');
});

test('the donation card links the Asset Store without a Ko-fi link, and drops a button without its image', () => {
const store = 'https://assetstore.unity.com/packages/package/1';
assert.equal(layout(`## Support\n\nSupport it on the [Asset Store](${store}).\n`, ['Website/docs/Images/support-card.svg']), '## Support\n\n'
+ `<a href="${store}"><img src="Website/docs/Images/support-card.svg" alt="Support it on the Asset Store." width="100%"></a>\n`);
});

test('images and the banner stay as they are, without a light variant', () => {
const banner = '<picture>\n <source srcset="a.webp" />\n <img src="a.png" alt="Banner" />\n</picture>';
assert.match(layout(`${banner}\n\n![Badge](badge.svg)`, ['a-light.png']), /<img src="a.png" alt="Banner" \/>\n<\/picture>\n\n!\[Badge\]\(badge.svg\)/);
Expand Down
7 changes: 4 additions & 3 deletions Website/scripts/intro-banner.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ for (const [language, file] of Object.entries(introduction)) {
assert.match(attribute(support, 'repo'), /^https:\/\/github\.com\/[^/]+\/[^/]+\/?$/);
});

test(`${language} introduction: the donation section becomes a card with a button to the Asset Store`, () => {
test(`${language} introduction: the donation section becomes a card with buttons to Ko-fi and the Asset Store`, () => {
const [donate, ...more] = find(tree, element('DonatePanel'));
assert.equal(more.length, 0);
assert.match(attribute(donate, 'href'), /^https:\/\/assetstore\.unity\.com\//);
assert.equal(find(donate, node => node.type === 'link').length, 0, 'the button carries the link');
assert.match(attribute(donate, 'kofi'), /^https:\/\/ko-fi\.com\//);
assert.match(attribute(donate, 'store'), /^https:\/\/assetstore\.unity\.com\//);
assert.equal(find(donate, node => node.type === 'link').length, 0, 'the buttons carry the links');
});

test(`${language} introduction: absolute links to the site become site links`, () => {
Expand Down
29 changes: 21 additions & 8 deletions Website/src/components/DonatePanel/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React from 'react';
import clsx from 'clsx';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import styles from './styles.module.css';

const TEXT = {
en: {title: 'Enjoying Aspid.FastTools?', action: 'Support on the Asset Store'},
ru: {title: 'Нравится Aspid.FastTools?', action: 'Поддержать в Asset Store'},
en: {title: 'Enjoying Aspid.FastTools?', kofi: 'Support on Ko-fi', store: 'Asset Store'},
ru: {title: 'Нравится Aspid.FastTools?', kofi: 'Поддержать на Ko-fi', store: 'Asset Store'},
};

const HEART = 'M12 21s-7.5-4.6-9.6-9.4C1 8.4 2.9 4.5 6.6 4.5c2.2 0 3.7 1.2 5.4 3.2 1.7-2 3.2-3.2 5.4-3.2 3.7 0 5.6 3.9 4.2 7.1C19.5 16.4 12 21 12 21Z';

/** The introduction's donation card: a beating heart, the README's sentence and a button to the Asset Store. */
export default function DonatePanel({href, children}) {
/**
* The introduction's donation card: a beating heart, the README's sentence, a filled button to Ko-fi and a quieter
* one to the Asset Store.
*/
export default function DonatePanel({kofi, store, children}) {
const {i18n} = useDocusaurusContext();
const text = TEXT[i18n.currentLocale] ?? TEXT.en;
return (
Expand All @@ -22,10 +26,19 @@ export default function DonatePanel({href, children}) {
<p className={styles.title}>{text.title}</p>
<p className={styles.text}>{children}</p>
</div>
<a className={styles.action} href={href} target="_blank" rel="noopener noreferrer">
<svg className={styles.icon} viewBox="0 0 24 24" aria-hidden="true"><path d={HEART} /></svg>
{text.action}
</a>
<div className={styles.actions}>
{kofi && (
<a className={styles.action} href={kofi} target="_blank" rel="noopener noreferrer">
<svg className={styles.icon} viewBox="0 0 24 24" aria-hidden="true"><path d={HEART} /></svg>
{text.kofi}
</a>
)}
{store && (
<a className={clsx(styles.action, kofi && styles.secondary)} href={store} target="_blank" rel="noopener noreferrer">
{text.store}
</a>
)}
</div>
</section>
);
}
13 changes: 12 additions & 1 deletion Website/src/components/DonatePanel/styles.module.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* The donation card closes the introduction, after the support panel. Unlike the quiet panels above it, it carries
* the brand green: a green wash with a glowing gradient frame, a heart that beats every few seconds and a filled
* button like the support panel's primary action, only larger.
* button to Ko-fi like the support panel's primary action, only larger, with an outlined Asset Store button under it.
*/

.donate {
Expand Down Expand Up @@ -50,6 +50,7 @@
display: inline-flex;
flex: none;
align-items: center;
justify-content: center;
gap: 10px;
padding: 13px 22px;
color: var(--venom-accent-fill-ink);
Expand All @@ -68,6 +69,16 @@
filter: brightness(1.06);
box-shadow: 0 12px 26px -10px var(--donate-green);
}
.actions { display: flex; flex: none; flex-direction: column; gap: 10px; }
/* The Asset Store button: the same size, outlined instead of filled, so Ko-fi stays the main action. */
:global(.markdown) a.action.secondary:not(:global(.card)):not(:global(.pagination-nav__link)):not([class*='card_']):not(:global(.table-of-contents__link)) {
color: var(--venom-fg-strong);
background: transparent;
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--donate-green) 55%, transparent);
}
:global(.markdown) a.action.secondary:not(:global(.card)):not(:global(.pagination-nav__link)):not([class*='card_']):not(:global(.table-of-contents__link)):hover {
box-shadow: inset 0 0 0 1px var(--donate-green);
}
.icon { flex: none; width: 17px; height: 17px; fill: currentColor; }
:global(.markdown) a.action:hover .icon { animation: beat 1.2s ease-in-out infinite; }

Expand Down
17 changes: 10 additions & 7 deletions Website/src/remark/introBanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,19 +234,22 @@ export default function remarkIntroBanner({baseUrl, siteUrl}) {
{type: 'mdxJsxAttribute', name: 'repo', value: repo},
]});
}
// The donation section — one sentence linking the Asset Store — becomes a card with a button to it; the link in
// the sentence turns into plain text, since the button carries it.
const isStore = (url) => /^https:\/\/assetstore\.unity\.com\//.test(url);
// The donation section — one sentence linking Ko-fi and the Asset Store — becomes a card with a button to each;
// the links in the sentence turn into plain text, since the buttons carry them.
const donation = {kofi: (url) => /^https:\/\/ko-fi\.com\//.test(url), store: (url) => /^https:\/\/assetstore\.unity\.com\//.test(url)};
const isDonation = (part) => part.type === 'link' && Object.values(donation).some((test) => test(part.url));
const donate = tree.children.findIndex((node, index) => node.type === 'heading' && node.depth === 2
&& tree.children[index + 1]?.type === 'paragraph'
&& tree.children[index + 1].children.some((part) => part.type === 'link' && isStore(part.url))
&& tree.children[index + 1].children.some(isDonation)
&& (!tree.children[index + 2] || tree.children[index + 2].type === 'heading'));
if (donate !== -1) {
const sentence = tree.children[donate + 1].children;
const store = sentence.find((part) => part.type === 'link' && isStore(part.url));
tree.children[donate + 1] = {type: 'mdxJsxFlowElement', name: 'DonatePanel',
attributes: [{type: 'mdxJsxAttribute', name: 'href', value: store.url}],
children: sentence.flatMap((part) => (part === store ? part.children : [part]))};
attributes: Object.entries(donation).flatMap(([name, test]) => {
const link = sentence.find((part) => part.type === 'link' && test(part.url));
return link ? [{type: 'mdxJsxAttribute', name, value: link.url}] : [];
}),
children: sentence.flatMap((part) => (isDonation(part) ? part.children : [part]))};
}
// Keep absolute site links on GitHub, and native local links on the site.
function visit(node) {
Expand Down
Loading