Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/registry-icon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@eisbachcode/emdash-plugin-analytics": patch
---

The plugin now has its own icon in the EmDash registry, in search results and on its page, instead of the letter placeholder. Also tested on EmDash 1.1.0, 1.2.0 and 1.3.0; none needed a change.
4 changes: 4 additions & 0 deletions emdash-plugin.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"release": {
"requires": { "env:emdash": ">=1.0.1" },
"artifacts": {
// Uploaded into each release record, not the profile, so it only
// shows from the next published version on. 256x256, rendered
// from icon.source.html.
"icon": { "file": "images/icon.png" },
"screenshots": [
{ "file": "images/analytics-page.png", "lang": "en" },
{ "file": "images/per-entry.png", "lang": "en" },
Expand Down
Binary file added images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 58 additions & 0 deletions images/icon.source.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!doctype html>
<!--
Source of icon.png (256x256, rendered at 1x): the registry icon, shown in
plugin search results and on the plugin page. The registry wants exactly
256x256 and at most 128 KB. Same language as banner.source.html: the
base-50 ground, faint ink waves, and EmDash's gradient on the one wave
that carries meaning, here a rising traffic line. No text, so no webfont,
and the registry rounds the corners itself.

Render from this folder:

"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless --disable-gpu --hide-scrollbars \
--force-device-scale-factor=1 --window-size=256,256 \
--screenshot="$PWD/icon.png" "file://$PWD/icon.source.html"
-->
<html lang="en">
<head>
<meta charset="utf-8" />
<style>
:root {
--base-50: oklch(3.5% 0.006 264);
--base-900: oklch(99% 0.018 102);
}
* { margin: 0; padding: 0; }
html, body { width: 256px; height: 256px; overflow: hidden; background: var(--base-50); }
svg { display: block; width: 256px; height: 256px; }
.ink { color: var(--base-900); opacity: 0.16; }
</style>
</head>
<body>
<svg viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<defs>
<linearGradient id="emdash-wave" x1="36" y1="0" x2="220" y2="0" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#281A81" />
<stop offset="0.22" stop-color="#911475" />
<stop offset="0.42" stop-color="#CE2F55" />
<stop offset="0.6" stop-color="#FF6633" />
<stop offset="0.8" stop-color="#FBAD41" />
<stop offset="1" stop-color="#FFE9CB" />
</linearGradient>
<linearGradient id="area" x1="0" y1="80" x2="0" y2="200" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#FF6633" stop-opacity="0.28" />
<stop offset="1" stop-color="#FF6633" stop-opacity="0" />
</linearGradient>
</defs>
<g class="ink" fill="none" stroke="currentColor" stroke-width="1.5">
<path d="M -10,70 C 30,58 60,84 100,78 C 140,72 170,52 210,58 C 236,62 252,72 270,70" />
<path d="M -10,214 C 30,204 60,226 100,220 C 140,214 170,198 210,204 C 236,208 252,216 270,214" />
</g>
<path fill="url(#area)"
d="M 36,176 C 58,170 66,150 86,154 C 106,158 112,174 132,164 C 152,154 158,118 180,112 C 196,108 206,94 220,84 L 220,200 L 36,200 Z" />
<path fill="none" stroke="url(#emdash-wave)" stroke-width="9" stroke-linecap="round" stroke-linejoin="round"
d="M 36,176 C 58,170 66,150 86,154 C 106,158 112,174 132,164 C 152,154 158,118 180,112 C 196,108 206,94 220,84" />
<circle cx="220" cy="84" r="11" fill="#FFE9CB" />
</svg>
</body>
</html>
4 changes: 2 additions & 2 deletions src/index/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
* Two things keep this cheap:
*
* - **It rides on the sync tick** rather than on `plugin:activate`, which
* is dispatched only by the admin Enable endpoint and never fires for a
* site that registers the plugin through `plugins: []`.
* fires once per activation (and, before EmDash 1.2.0, never for a site
* that registers the plugin through `plugins: []`).
* - **It walks a few entries per tick.** `getPublicUrl()` is one bridge
* call per entry and a sandboxed invocation gets ten in total, so the
* page size is deliberately tiny and the pass spreads over many ticks.
Expand Down
10 changes: 6 additions & 4 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,11 @@ const CRON_TIMEOUT_MS = 30_000;
const plugin: SandboxedPlugin = {
hooks: {
/**
* Fires only when an administrator clicks Enable. A site that
* registers the plugin through `plugins: []` never gets one, which is
* why this is not the only place scheduling happens.
* Fires when an administrator clicks Enable, and from EmDash 1.2.0 also
* on the first start of a site that registers the plugin through
* `plugins: []`. Before 1.2.0 such a site never gets one, which is
* why this is not the only place scheduling happens. It must not
* throw: from 1.2.0 a throwing activate hook disables the plugin.
*/
"plugin:activate": async (_event, ctx) => {
await scheduleFromSettings(ctx);
Expand Down Expand Up @@ -101,7 +103,7 @@ const plugin: SandboxedPlugin = {
errorPolicy: "continue",
handler: async (event, ctx) => {
// Also the reliable scheduling entry point for `plugins: []`
// installs, where `plugin:activate` never fires.
// installs before EmDash 1.2.0, where `plugin:activate` never fires.
await scheduleFromSettings(ctx);
await index(ctx, event, "published");
},
Expand Down
12 changes: 6 additions & 6 deletions src/sync/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,12 @@ export interface SyncOutcome {
* Schedule both tasks, idempotently.
*
* Called from `plugin:activate`, from the content hooks and from the
* widget's first `page_load` — because `plugin:activate` is dispatched
* only by the admin Enable endpoint, and a plugin registered through
* `plugins: []` in the site config never gets one. That is the npm
* channel, which is the channel most installs use. `CronAccess.schedule`
* upserts on (plugin, task), so calling it repeatedly is free of
* consequence.
* widget's first `page_load` — because before EmDash 1.2.0
* `plugin:activate` is dispatched only by the admin Enable endpoint, and a
* plugin registered through `plugins: []` in the site config never gets
* one. That is the npm channel, which is the channel most installs use.
* `CronAccess.schedule` upserts on (plugin, task), so calling it repeatedly
* is free of consequence.
*/
export async function ensureScheduled(ctx: PluginContext, interval: string): Promise<void> {
if (!ctx.cron) return;
Expand Down
Loading