Skip to content

Commit 7777dda

Browse files
committed
feat: phoenix pro upgrade dialog
1 parent d1887b0 commit 7777dda

File tree

6 files changed

+231
-4
lines changed

6 files changed

+231
-4
lines changed

src/nls/root/strings.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1662,5 +1662,18 @@ define({
16621662
"CUSTOM_SNIPPETS_HEADER_ABBREVIATION": "Abbreviation",
16631663
"CUSTOM_SNIPPETS_HEADER_TEMPLATE": "Template Text",
16641664
"CUSTOM_SNIPPETS_HEADER_DESCRIPTION": "Description",
1665-
"CUSTOM_SNIPPETS_HEADER_FILE_EXTENSION": "File Extension"
1665+
"CUSTOM_SNIPPETS_HEADER_FILE_EXTENSION": "File Extension",
1666+
1667+
// promos
1668+
"PROMO_UPGRADE_TITLE": "You’ve been upgraded to {0}",
1669+
"PROMO_UPGRADE_MESSAGE": "Enjoy full access to all premium features for the next {0} days:",
1670+
"PROMO_CARD_1": "Drag & Drop Elements",
1671+
"PROMO_CARD_1_MESSAGE": "Rearrange sections visually — Phoenix updates the HTML & CSS for you.",
1672+
"PROMO_CARD_2": "Image Replacement",
1673+
"PROMO_CARD_2_MESSAGE": "Click any image to replace it instantly and preview changes in real time.",
1674+
"PROMO_CARD_3": "Element Duplication and Deletion",
1675+
"PROMO_CARD_3_MESSAGE": "Duplicate and delete elements with a single click.",
1676+
"PROMO_CARD_4": "Editing Text In Preview",
1677+
"PROMO_CARD_4_MESSAGE": "Edit headings, buttons, and copy directly in the preview.",
1678+
"PROMO_LEARN_MORE": "Learn More\u2026"
16661679
});

src/services/html/pro-upgrade.html

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<div class="browser-login-waiting-dialog modal">
2+
<style>
3+
/* Local tokens mapped to your dark palette */
4+
.browser-login-waiting-dialog {
5+
--bg: #1c1c1e; /* @dark-bc-bg-status-bar */
6+
--card-bg: #313131; /* @dark-bc-panel-bg-alt */
7+
--card-bg-hover: #2c2c2c; /* @dark-bc-panel-bg */
8+
--card-border: rgba(255,255,255,0.06);
9+
--card-border-hover: rgba(255,255,255,0.12);
10+
--text: #ffffff; /* @dark-bc-text-alt */
11+
--text-muted: #9a9a9a; /* @dark-bc-text-quiet */
12+
--text-medium: #cccccc; /* @dark-bc-text-medium */
13+
--thumb-bg: #1b1b1b; /* @dark-bc-bg-inline-widget */
14+
--focus: #1473e6; /* highlight/focus blue */
15+
--link: #6bbeff; /* @dark-bc-text-link */
16+
}
17+
18+
.modal-header .dialog-title {
19+
color: var(--text);
20+
}
21+
22+
.features-grid {
23+
display: grid;
24+
grid-template-columns: repeat(2, 1fr);
25+
gap: 16px;
26+
}
27+
28+
.feature-card {
29+
background: var(--card-bg);
30+
border: 1px solid var(--card-border);
31+
border-radius: 5px;
32+
overflow: hidden;
33+
display: flex;
34+
flex-direction: column;
35+
transition: background 0.15s ease, border-color 0.15s ease;
36+
}
37+
38+
.feature-card:hover {
39+
background: var(--card-bg-hover);
40+
border-color: var(--card-border-hover);
41+
}
42+
43+
.feature-card:focus-within {
44+
outline: 2px solid var(--focus);
45+
outline-offset: 2px;
46+
}
47+
48+
.feature-thumb {
49+
width: 100%;
50+
height: 120px;
51+
object-fit: cover;
52+
background: var(--thumb-bg);
53+
}
54+
55+
.feature-body {
56+
padding: 12px;
57+
}
58+
59+
.feature-body h2 {
60+
margin: 0 0 6px;
61+
font-size: 15px;
62+
color: var(--text);
63+
}
64+
65+
.feature-body p {
66+
margin: 0;
67+
font-size: 13px;
68+
color: var(--text-muted);
69+
line-height: 1.35;
70+
}
71+
72+
.waiting-content-container > p {
73+
margin-bottom: 20px;
74+
font-size: 14px;
75+
color: var(--text-medium);
76+
}
77+
78+
.phoenix-pro-title {
79+
background: linear-gradient(45deg,#ff8c42,#ffa500,#ffcc70,#ffd700);
80+
background-clip: text;
81+
-webkit-background-clip: text;
82+
color: transparent;
83+
-webkit-text-fill-color: transparent;
84+
display: inline-block;
85+
}
86+
87+
.browser-login-waiting-dialog a {
88+
color: var(--link);
89+
text-decoration: none;
90+
}
91+
.browser-login-waiting-dialog a:hover {
92+
text-decoration: underline;
93+
}
94+
</style>
95+
96+
<div class="modal-header">
97+
<h1 class="dialog-title">{{{title}}}</h1>
98+
</div>
99+
100+
<div class="modal-body" style="max-height: 550px;">
101+
<div class="waiting-content-container">
102+
<p style="margin-bottom: 20px; color: #aaa; font-size: 14px;">
103+
{{message}}
104+
</p>
105+
106+
<div class="features-grid">
107+
<!-- Card 1 -->
108+
<div class="feature-card">
109+
<img src="https://docs-images.phcode.dev/phcode-sdk/quick-view-image.png" alt="{{Strings.PROMO_CARD_1}}" class="feature-thumb">
110+
<div class="feature-body">
111+
<h2>{{Strings.PROMO_CARD_1}}</h2>
112+
<p>{{Strings.PROMO_CARD_1_MESSAGE}}</p>
113+
</div>
114+
</div>
115+
116+
<!-- Card 2 -->
117+
<div class="feature-card">
118+
<img src="https://docs-images.phcode.dev/phcode-sdk/quick-view-image.png" alt="{{Strings.PROMO_CARD_2}}" class="feature-thumb">
119+
<div class="feature-body">
120+
<h2>{{Strings.PROMO_CARD_2}}</h2>
121+
<p>{{Strings.PROMO_CARD_2_MESSAGE}}</p>
122+
</div>
123+
</div>
124+
125+
<!-- Card 3 -->
126+
<div class="feature-card">
127+
<img src="https://docs-images.phcode.dev/phcode-sdk/quick-view-image.png" alt="{{Strings.PROMO_CARD_3}}" class="feature-thumb">
128+
<div class="feature-body">
129+
<h2>{{Strings.PROMO_CARD_3}}</h2>
130+
<p>{{Strings.PROMO_CARD_3_MESSAGE}}</p>
131+
</div>
132+
</div>
133+
134+
<!-- Card 4 -->
135+
<div class="feature-card">
136+
<img src="https://docs-images.phcode.dev/phcode-sdk/quick-view-image.png" alt="{{Strings.PROMO_CARD_4}}" class="feature-thumb">
137+
<div class="feature-body">
138+
<h2>{{Strings.PROMO_CARD_4}}</h2>
139+
<p>{{Strings.PROMO_CARD_4_MESSAGE}}</p>
140+
</div>
141+
</div>
142+
</div>
143+
</div>
144+
</div>
145+
146+
<div class="modal-footer">
147+
<button class="dialog-button btn" data-button-id="learn_more">{{Strings.PROMO_LEARN_MORE}}</button>
148+
<button class="dialog-button btn primary" data-button-id="ok">{{Strings.OK}}</button>
149+
</div>
150+
</div>

src/services/pro-dialogs.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* GNU AGPL-3.0 License
3+
*
4+
* Copyright (c) 2021 - present core.ai . All rights reserved.
5+
*
6+
* This program is free software: you can redistribute it and/or modify it under
7+
* the terms of the GNU Affero General Public License as published by the Free
8+
* Software Foundation, either version 3 of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11+
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
16+
*
17+
*/
18+
19+
/*global logger*/
20+
21+
/**
22+
* Phoenix pro pre and post promo dialogs
23+
* shows dialog where we give Phoenix pro to all users on app install
24+
* and dialogs on pro trial ends.
25+
*
26+
*/
27+
28+
define(function (require, exports, module) {
29+
const proTitle = `<span class="phoenix-pro-title">
30+
<span class="pro-plan-name">Phoenix Pro</span>
31+
<i class="fa-solid fa-feather orange-gold" style="margin-left: 3px;"></i>
32+
</span>`;
33+
require("./setup-login-service"); // this adds loginService to KernalModeTrust
34+
const Dialogs = require("widgets/Dialogs"),
35+
Mustache = require("thirdparty/mustache/mustache"),
36+
Strings = require("strings"),
37+
StringUtils = require("utils/StringUtils"),
38+
proUpgradeHTML = require("text!./html/pro-upgrade.html");
39+
40+
function showProUpgradeDialog(trialDays) {
41+
const title = StringUtils.format(Strings.PROMO_UPGRADE_TITLE, proTitle);
42+
const message = StringUtils.format(Strings.PROMO_UPGRADE_MESSAGE, trialDays);
43+
const $template = $(Mustache.render(proUpgradeHTML, {title, message, Strings}));
44+
Dialogs.showModalDialogUsingTemplate($template).done(function (id) {
45+
console.log("Dialog closed with id: " + id);
46+
if(id === 'learn_more') {
47+
Phoenix.app.openURLInDefaultBrowser(brackets.config.homepage_url);
48+
}
49+
});
50+
}
51+
52+
exports.showProUpgradeDialog = showProUpgradeDialog;
53+
});

src/services/promotions.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ define(function (require, exports, module) {
3333

3434
require("./setup-login-service"); // this adds loginService to KernalModeTrust
3535
const Metrics = require("utils/Metrics"),
36-
semver = require("thirdparty/semver.browser");
36+
semver = require("thirdparty/semver.browser"),
37+
ProDialogs = require("./pro-dialogs");
3738

3839
const KernalModeTrust = window.KernalModeTrust;
3940
if (!KernalModeTrust) {
@@ -242,6 +243,7 @@ define(function (require, exports, module) {
242243
Metrics.countEvent(Metrics.EVENT_TYPE.PRO, "trial", "activated");
243244
console.log(`Pro trial activated for ${trialDays} days`);
244245

246+
ProDialogs.showProUpgradeDialog(trialDays);
245247
// Trigger the event for UI to handle
246248
LoginService.trigger(EVENT_PRO_UPGRADE_ON_INSTALL, {
247249
trialDays: trialDays,

src/styles/brackets.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ html, body {
8383
}
8484

8585
#phcode-io-main-nav.phoenix-pro{
86-
background: @phoenix-pro-gradient;
86+
background: @phoenix-pro-gradient-dark;
8787
background-clip: text;
8888
-webkit-background-clip: text; /* Chrome, Safari */
8989
color: transparent; /* works in Firefox */

src/styles/brackets_core_ui_variables.less

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,19 @@
281281
@dark-css-codehint-icon: #146a41;
282282

283283
// phoenix pro
284-
@phoenix-pro-gradient: linear-gradient(
284+
@phoenix-pro-gradient-dark: linear-gradient(
285285
45deg,
286286
#ff8c42, /* deep orange */
287287
#ffa500, /* bright orange */
288288
#ffcc70, /* golden yellow */
289289
#ffd700 /* rich gold */
290290
);
291+
292+
@phoenix-pro-gradient-light: linear-gradient(
293+
45deg,
294+
#cc5500 0%, /* burnt orange */
295+
#ff7a1a 25%, /* strong orange */
296+
#ff9900 50%, /* vibrant orange-gold */
297+
#e6a600 75%, /* darker amber */
298+
#c99700 100% /* rich golden brown */
299+
);

0 commit comments

Comments
 (0)