Skip to content
Open
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
3 changes: 2 additions & 1 deletion packages/web/src/lib/marketing/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type Integration = {
categoryLabel: string;
tag?: string;
platform?: string;
version?: string;
cta: 'install' | 'docs';
color?: string;
fg?: string;
Expand Down Expand Up @@ -106,7 +107,7 @@ export const integrationCategories: IntegrationCategory[] = [
items: [
{
id: 'vscode',
name: 'Visual Studio Code',
name: 'VS Code',
desc: 'Marketplace extension.',
href: marketingLinks.vscode,
platform: 'VS Code, Cursor',
Expand Down
69 changes: 69 additions & 0 deletions packages/web/src/lib/marketing/versions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { writable } from 'svelte/store';

export const liveVersions = writable<Record<string, string>>({
firefox: '',
js: '',
rust: '',
vscode: '',
});

export async function loadLiveVersions() {
// 1. Firefox Addon
try {
Comment on lines +10 to +12
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love a brief doc-comment that explains what this function does. Also, is there a reason you don't simply return a memoized copy of the liveVersions object? If you do, we can reduce the number of exports from this module.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love a brief doc-comment that explains what this function does.

Will do.

Also, is there a reason you don't simply return a memoized copy of the liveVersions object? If you do, we can reduce the number of exports from this module.

I'm not sure I really understand.

const ver = (
await (
await fetch(
'https://addons.mozilla.org/api/v5/addons/addon/private-grammar-checker-harper/',
)
).json()
).current_version.version;
liveVersions.update((v) => ({ ...v, firefox: ver }));
} catch {}

// 2. JS Package
try {
const ver = (await (await fetch('https://registry.npmjs.org/harper.js')).json())['dist-tags']
.latest;
liveVersions.update((v) => ({ ...v, js: ver }));
} catch {}

// 3. Rust Crate
try {
const lines = (await (await fetch('https://index.crates.io/ha/rp/harper-core')).text()).split(
'\n',
);
liveVersions.update((v) => ({ ...v, rust: JSON.parse(lines[lines.length - 2]).vers }));
} catch {}

// 4. VS Code Extension
try {
const res = await fetch(
'https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json;api-version=3.0-preview.1',
},
body: JSON.stringify({
filters: [
{
criteria: [
{ filterType: 8, value: 'Microsoft.VisualStudio.Code' },
{ filterType: 7, value: 'elijah-potter.harper' },
],
pageNumber: 1,
pageSize: 1,
sortBy: 0,
sortOrder: 0,
},
],
assetTypes: [],
flags: 194,
}),
},
);
const ver = (await res.json()).results[0].extensions[0].versions[0].version;
liveVersions.update((v) => ({ ...v, vscode: ver }));
} catch {}
}
21 changes: 19 additions & 2 deletions packages/web/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import PrivacySpeedCards from '$lib/marketing/PrivacySpeedCards.svelte';
import { featuredIntegrationIds, integrations, marketingLinks } from '$lib/marketing/data';
import { LazyEditor } from 'harper-editor';
import type { Linter } from 'harper.js';
import { loadLiveVersions, liveVersions } from '$lib/marketing/versions';
import { onMount } from 'svelte';
import demoText from '../../../../demo.md?raw';

Expand Down Expand Up @@ -141,10 +142,17 @@ const faqs = [
},
];

let liveFxVer = '';
let liveJsVer = '';
let liveRustVer = '';
let liveVscodeVer = '';

onMount(() => {
void (async () => {
linter = await createEditorLinter();
})();

void loadLiveVersions();
});

</script>
Expand Down Expand Up @@ -246,8 +254,17 @@ onMount(() => {
>
<IntegrationTile {integration} size={32} />
<span class="flex min-w-0 flex-col">
<strong class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.84rem]">{integration.name}</strong>
<small class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.72rem] text-[#807a6e] dark:text-white/55">{integration.desc}</small>
<div class="flex items-center gap-1.5 overflow-hidden">
<strong class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.84rem]">{integration.name}</strong>
{#if $liveVersions[integration.id]}
<span class="inline-flex items-center rounded-full bg-[#f4f1ea] dark:bg-white/10 px-1.5 py-0.5 text-[0.65rem] font-mono font-medium text-[#6b6455] dark:text-white/80 border border-[#e4dfd3] dark:border-white/10 select-none">
v{$liveVersions[integration.id]}
</span>
{/if}
Comment on lines +258 to +263
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to have a small bit of hover text (which you can simply do with the title attribute) that explains why we are showing a version number there.

Something like, "This version is slightly behind the core engine due to a delay".

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I was wondering about something like that, sounds like a way to handle it.
Do you think I should also add the current version? We don't already display it anywhere. I'm not sure where it would look the best either.

</div>
<small class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.72rem] text-[#807a6e] dark:text-white/55">
{integration.desc}
</small>
</span>
</a>
{/if}
Expand Down
46 changes: 39 additions & 7 deletions packages/web/src/routes/get/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import { onMount } from 'svelte';
import {
type Integration,
integrationCategories,
Expand All @@ -8,10 +9,15 @@ import {
import IntegrationTile from '$lib/marketing/IntegrationTile.svelte';
import MarketingFooter from '$lib/marketing/MarketingFooter.svelte';
import MarketingHeader from '$lib/marketing/MarketingHeader.svelte';
import { liveVersions, loadLiveVersions } from '$lib/marketing/versions';

let activeCategory = 'all';
let query = '';

onMount(() => {
void loadLiveVersions();
});

$: filtered = integrations.filter((integration) => {
if (activeCategory === 'community' && !integration.community) {
return false;
Expand Down Expand Up @@ -77,8 +83,21 @@ function clearFilters() {
>
<IntegrationTile {integration} size={40} />
<span class="flex min-w-0 flex-col">
<strong class="text-[0.94rem] leading-[1.25]">{integration.name}</strong>
<small class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.8rem] leading-[1.4] text-[#807a6e] dark:text-white/55">{integration.desc}</small>
<div class="flex items-center gap-1.5">
<strong class="text-[0.94rem] leading-[1.25]">{integration.name}</strong>
{#if $liveVersions[integration.id]}
<span class="inline-flex items-center rounded-full bg-[#f4f1ea] dark:bg-white/10 px-1.5 py-0.5 text-[0.68rem] font-mono font-medium text-[#6b6455] dark:text-white/80 border border-[#e4dfd3] dark:border-white/10 select-none">
{$liveVersions[integration.id]}
</span>
{:else if $liveVersions[integration.name]}
<span class="inline-flex items-center rounded-full bg-[#f4f1ea] dark:bg-white/10 px-1.5 py-0.5 text-[0.68rem] font-mono font-medium text-[#6b6455] dark:text-white/80 border border-[#e4dfd3] dark:border-white/10 select-none">
{$liveVersions[integration.name]}
</span>
{/if}
</div>
<small class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.8rem] leading-[1.4] text-[#807a6e] dark:text-white/55">
{integration.desc}
</small>
</span>
<em class="whitespace-nowrap text-[0.78rem] font-extrabold text-[#b06a1b] not-italic dark:text-primary-300">{ctaLabel(integration)} →</em>
</a>
Expand Down Expand Up @@ -168,12 +187,25 @@ function clearFilters() {
class="grid grid-cols-[2.5rem_1fr_auto] items-center gap-[0.9rem] rounded-xl border-[0.5px] border-[rgba(28,26,22,0.1)] bg-white px-[1.1rem] py-[0.9rem] !text-[#1c1a16] no-underline transition-[transform,box-shadow,border-color] duration-150 hover:-translate-y-px hover:border-[#b06a1b] hover:shadow-[0_10px_24px_-16px_rgba(28,26,22,0.16)] hover:no-underline dark:border-white/10 dark:bg-white/5 dark:!text-white dark:hover:border-primary-300 max-[640px]:grid-cols-[2.5rem_1fr] [&_em]:max-[640px]:col-start-2"
href={integration.href}
>
<IntegrationTile {integration} size={40} />
<span class="flex min-w-0 flex-col">
<IntegrationTile {integration} size={40} />
<span class="flex min-w-0 flex-col">
<div class="flex items-center gap-1.5">
<strong class="text-[0.94rem] leading-[1.25]">{integration.name}</strong>
<small class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.8rem] leading-[1.4] text-[#807a6e] dark:text-white/55">{integration.platform}</small>
</span>
<em class="whitespace-nowrap text-[0.78rem] font-extrabold text-[#b06a1b] not-italic dark:text-primary-300">{ctaLabel(integration)} →</em>
{#if $liveVersions[integration.id]}
<span class="inline-flex items-center rounded-full bg-[#f4f1ea] dark:bg-white/10 px-1.5 py-0.5 text-[0.68rem] font-mono font-medium text-[#6b6455] dark:text-white/80 border border-[#e4dfd3] dark:border-white/10 select-none">
{$liveVersions[integration.id]}
</span>
{:else if $liveVersions[integration.name]}
<span class="inline-flex items-center rounded-full bg-[#f4f1ea] dark:bg-white/10 px-1.5 py-0.5 text-[0.68rem] font-mono font-medium text-[#6b6455] dark:text-white/80 border border-[#e4dfd3] dark:border-white/10 select-none">
{$liveVersions[integration.name]}
</span>
{/if}
</div>
<small class="overflow-hidden text-ellipsis whitespace-nowrap text-[0.8rem] leading-[1.4] text-[#807a6e] dark:text-white/55">
{integration.platform}
</small>
</span>
<em class="whitespace-nowrap text-[0.78rem] font-extrabold text-[#b06a1b] not-italic dark:text-primary-300">{ctaLabel(integration)} →</em>
</a>
{/each}
{/if}
Expand Down
Loading