Skip to content

Commit b6ce436

Browse files
committed
feat(mdviewer): show crown icon on edit button for free users
Add a gold crown icon after the "Edit" text to indicate it's a Pro feature, so free users know before clicking. Pro status is sent from Phoenix to the md viewer iframe via MDVIEWR_SET_PRO_STATUS message on iframe ready and on entitlement changes.
1 parent 528584c commit b6ce436

5 files changed

Lines changed: 43 additions & 3 deletions

File tree

src-mdviewer/src/bridge.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,9 @@ export function initBridge() {
269269
case "MDVIEWR_SET_THEME":
270270
handleSetTheme(data);
271271
break;
272+
case "MDVIEWR_SET_PRO_STATUS":
273+
setState({ isPro: !!data.isPro });
274+
break;
272275
case "MDVIEWR_SET_EDIT_MODE":
273276
handleSetEditMode(data);
274277
break;

src-mdviewer/src/components/embedded-toolbar.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import {
3434
Image as ImageIcon,
3535
Upload,
3636
Sun,
37-
Moon
37+
Moon,
38+
Crown
3839
} from "lucide";
3940
import { on, emit } from "../core/events.js";
4041
import { getState, setState } from "../core/state.js";
@@ -57,7 +58,7 @@ const _isMacWebKit = /Mac/.test(navigator.platform)
5758
&& !/Chrome|CriOS|Edg|Firefox|FxiOS/.test(navigator.userAgent);
5859

5960
const allIcons = { Bold, Italic, Strikethrough, Underline, Code, Link, List, ListOrdered,
60-
ListChecks, Quote, Minus, Table, FileCode, ChevronDown, Type, MoreHorizontal, Pencil, BookOpen, Link2, Link2Off, Printer, Image: ImageIcon, Upload, Sun, Moon };
61+
ListChecks, Quote, Minus, Table, FileCode, ChevronDown, Type, MoreHorizontal, Pencil, BookOpen, Link2, Link2Off, Printer, Image: ImageIcon, Upload, Sun, Moon, Crown };
6162

6263
export function initEmbeddedToolbar() {
6364
toolbar = document.getElementById("toolbar");
@@ -67,6 +68,7 @@ export function initEmbeddedToolbar() {
6768

6869
on("state:editMode", () => render());
6970
on("state:theme", () => render());
71+
on("state:isPro", () => render());
7072
on("editor:selection-state", updateFormatState);
7173
on("state:locale", () => render());
7274
}
@@ -102,9 +104,10 @@ function renderReadMode() {
102104
<i data-lucide="link-2" class="sync-on-icon"${cursorSyncEnabled ? "" : ' style="display:none"'}></i>
103105
<i data-lucide="link-2-off" class="sync-off-icon"${cursorSyncEnabled ? ' style="display:none"' : ""}></i>
104106
</button>
105-
<button class="edit-toggle-btn" id="emb-edit-btn" title="${t("toolbar.switch_to_edit") || "Switch to edit mode"}">
107+
<button class="edit-toggle-btn${getState().isPro === false ? " pro-locked" : ""}" id="emb-edit-btn" title="${t("toolbar.switch_to_edit") || "Switch to edit mode"}">
106108
<i data-lucide="pencil"></i>
107109
<span>${t("toolbar.edit") || "Edit"}</span>
110+
${getState().isPro === false ? '<i data-lucide="crown" class="pro-crown-icon"></i>' : ""}
108111
</button>
109112
</div>`;
110113

src-mdviewer/src/styles/app.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,16 @@ html, body {
198198
border-color: var(--color-border);
199199
}
200200

201+
/* Crown icon shown after "Edit" text for free users — indicates a Pro feature */
202+
.embedded-toolbar .edit-toggle-btn .pro-crown-icon {
203+
color: #f0b400;
204+
margin-left: 2px;
205+
}
206+
.embedded-toolbar .edit-toggle-btn .pro-crown-icon svg {
207+
width: 12px;
208+
height: 12px;
209+
}
210+
201211
.embedded-toolbar .format-btn {
202212
width: 22px;
203213
height: 22px;

src/extensionsIntegrated/Phoenix-live-preview/MarkdownSync.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,25 @@ define(function (require, exports, module) {
455455
_sendTheme();
456456
}
457457

458+
/**
459+
* Push the Pro edit entitlement state to the iframe so it can show/hide
460+
* the crown upsell indicator on the Edit button.
461+
* @param {boolean} isPro
462+
*/
463+
function sendProStatus(isPro) {
464+
if (!_active || !_iframeReady) {
465+
return;
466+
}
467+
const iframeWindow = _getIframeWindow();
468+
if (!iframeWindow) {
469+
return;
470+
}
471+
iframeWindow.postMessage({
472+
type: "MDVIEWR_SET_PRO_STATUS",
473+
isPro: !!isPro
474+
}, "*");
475+
}
476+
458477
function _sendLocale() {
459478
if (!_active || !_iframeReady) {
460479
return;
@@ -1128,5 +1147,6 @@ define(function (require, exports, module) {
11281147
exports.setIframeReadyHandler = setIframeReadyHandler;
11291148
exports.setCursorSyncEnabled = setCursorSyncEnabled;
11301149
exports.sendThemeOverride = sendThemeOverride;
1150+
exports.sendProStatus = sendProStatus;
11311151
exports.setThemeToggleHandler = function(handler) { _onThemeToggle = handler; };
11321152
});

src/extensionsIntegrated/Phoenix-live-preview/main.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ define(function (require, exports, module) {
202202
isProEditUser = entitlement && entitlement.activated;
203203
// Sync edit mode with md iframe on entitlement change
204204
if (_isMdviewrActive && $iframe && $iframe[0] && $iframe[0].contentWindow) {
205+
// Push pro status to iframe so it can toggle the crown indicator
206+
MarkdownSync.sendProStatus(isProEditUser);
205207
if (isProEditUser && !wasProEditUser) {
206208
// Just got pro — switch to edit mode
207209
$iframe[0].contentWindow.postMessage(
@@ -1572,6 +1574,8 @@ define(function (require, exports, module) {
15721574
// When iframe first loads, send initial edit mode based on entitlement
15731575
MarkdownSync.setIframeReadyHandler(function () {
15741576
_updateLPControlsForMdviewer();
1577+
// Push pro status so the iframe can show the crown upsell indicator
1578+
MarkdownSync.sendProStatus(isProEditUser);
15751579
// Pro users default to edit mode on first load
15761580
if (isProEditUser) {
15771581
MarkdownSync.setEditMode(true);

0 commit comments

Comments
 (0)