Skip to content

Commit 4f0469d

Browse files
committed
deploy: 606b7d0
1 parent b0e2032 commit 4f0469d

File tree

61 files changed

+944
-844
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+944
-844
lines changed

LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ function RemoteFunctions(config = {}) {
3333
// we need this so that we can remove click styling from the previous element when a new element is clicked
3434
let previouslyClickedElement = null;
3535

36+
// this is needed so that when user starts typing we can dismiss all the boxes and highlights
37+
// now with this variable we check if its a first keystroke on an element or a subsequent keystroke
38+
let _uiHiddenDuringTyping = false;
39+
3640
var req, timeout;
3741
var animateHighlight = function (time) {
3842
if(req) {
@@ -1577,10 +1581,6 @@ function RemoteFunctions(config = {}) {
15771581
create: function() {
15781582
this.remove(); // remove existing box if already present
15791583

1580-
if(!config.isProUser) {
1581-
return;
1582-
}
1583-
15841584
// this check because when there is no element visible to the user, we don't want to show the box
15851585
// for ex: when user clicks on a 'x' button and the button is responsible to hide a panel
15861586
// then clicking on that button shouldn't show the more options box
@@ -3822,6 +3822,9 @@ function RemoteFunctions(config = {}) {
38223822
* @param {Element} element - The DOM element to select
38233823
*/
38243824
function _selectElement(element) {
3825+
// user selected a new element, we need to reset this variable
3826+
_uiHiddenDuringTyping = false;
3827+
38253828
dismissNodeMoreOptionsBox();
38263829
dismissAIPromptBox();
38273830
dismissNodeInfoBox();
@@ -3931,12 +3934,7 @@ function RemoteFunctions(config = {}) {
39313934
event.stopPropagation();
39323935
event.stopImmediatePropagation();
39333936

3934-
// when in click mode, only select dynamic elements (without data-brackets-id) directly
3935-
// as for static elements, the editor will handle selection via highlight message
3936-
if (!shouldShowHighlightOnHover() && !element.hasAttribute("data-brackets-id")) {
3937-
_selectElement(element);
3938-
}
3939-
3937+
_selectElement(element);
39403938
activateHoverLock();
39413939
}
39423940
}
@@ -4021,7 +4019,10 @@ function RemoteFunctions(config = {}) {
40214019
var foundValidElement = false;
40224020
for (i = 0; i < nodes.length; i++) {
40234021
if(isElementInspectable(nodes[i], true) && nodes[i].tagName !== "BR") {
4024-
_selectElement(nodes[i]);
4022+
// only call _selectElement if it's a different element to avoid unnecessary box recreation
4023+
if (previouslyClickedElement !== nodes[i]) {
4024+
_selectElement(nodes[i]);
4025+
}
40254026
foundValidElement = true;
40264027
break;
40274028
}
@@ -4431,8 +4432,14 @@ function RemoteFunctions(config = {}) {
44314432

44324433
this.rememberedNodes = {};
44334434

4434-
// update highlight after applying diffs
4435-
redrawEverything();
4435+
// when user starts typing in the editor we hide all the boxes and highlights
4436+
// _uiHiddenDuringTyping variable keeps track if its a first keystroke or subsequent
4437+
// so that we don't end up calling dismiss/hide kinda functions multiple times
4438+
if (!_uiHiddenDuringTyping) {
4439+
dismissUIAndCleanupState();
4440+
hideHighlight();
4441+
_uiHiddenDuringTyping = true;
4442+
}
44364443
};
44374444

44384445
function applyDOMEdits(edits) {

LiveDevelopment/main.js

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ define(function main(require, exports, module) {
4848
EditorManager = require("editor/EditorManager");
4949

5050

51-
// this is responsible to make the advanced live preview features active or inactive
52-
// @abose (make the first value true when its a paid user, everything rest is handled automatically)
53-
let isProUser = window.KernalModeTrust ? true : false;
54-
// when isFreeTrialUser is true isProUser should also be true
55-
// when its false, isProUser can be true/false doesn't matter
56-
let isFreeTrialUser = true;
51+
const KernalModeTrust = window.KernalModeTrust;
52+
53+
// this will later be assigned its correct values once entitlementsManager loads
54+
let isProUser = false;
55+
let isFreeTrialUser = false;
5756

5857
const EVENT_LIVE_HIGHLIGHT_PREF_CHANGED = "liveHighlightPrefChange";
58+
const PREFERENCE_LIVE_PREVIEW_MODE = "livePreviewMode";
5959

6060
// state manager key to track image gallery selected state, by default we keep this as selected
6161
// if this is true we show the image gallery when an image element is clicked
@@ -316,6 +316,69 @@ define(function main(require, exports, module) {
316316
return false;
317317
}
318318

319+
// default mode means on first load for pro user we have edit mode
320+
// for free user we have highlight mode
321+
function _getDefaultMode() {
322+
return isProUser ? "edit" : "highlight";
323+
}
324+
325+
// to set that mode in the preferences
326+
function _initializeMode() {
327+
if (isFreeTrialUser) {
328+
PreferencesManager.set(PREFERENCE_LIVE_PREVIEW_MODE, "edit");
329+
return;
330+
}
331+
332+
const savedMode = PreferencesManager.get(PREFERENCE_LIVE_PREVIEW_MODE) || _getDefaultMode();
333+
334+
if (savedMode === "highlight" && isProUser) {
335+
PreferencesManager.set(PREFERENCE_LIVE_PREVIEW_MODE, "edit");
336+
} else if (savedMode === "edit" && !isProUser) {
337+
PreferencesManager.set(PREFERENCE_LIVE_PREVIEW_MODE, "highlight");
338+
}
339+
}
340+
341+
// this is called everytime there is a change in entitlements
342+
async function _updateProUserStatus() {
343+
if (!KernalModeTrust) {
344+
return;
345+
}
346+
347+
try {
348+
const entitlement = await KernalModeTrust.EntitlementsManager.getLiveEditEntitlement();
349+
350+
isProUser = entitlement.activated;
351+
isFreeTrialUser = await KernalModeTrust.EntitlementsManager.isInProTrial();
352+
353+
config.isProUser = isProUser;
354+
exports.isProUser = isProUser;
355+
exports.isFreeTrialUser = isFreeTrialUser;
356+
357+
_initializeMode();
358+
359+
if (MultiBrowserLiveDev.status >= MultiBrowserLiveDev.STATUS_ACTIVE) {
360+
MultiBrowserLiveDev.updateConfig(JSON.stringify(config));
361+
MultiBrowserLiveDev.registerHandlers();
362+
}
363+
} catch (error) {
364+
console.error("Error updating pro user status:", error);
365+
isProUser = false;
366+
isFreeTrialUser = false;
367+
}
368+
}
369+
370+
function setMode(mode) {
371+
if (mode === "edit" && !exports.isProUser) {
372+
return false;
373+
}
374+
PreferencesManager.set(PREFERENCE_LIVE_PREVIEW_MODE, mode);
375+
return true;
376+
}
377+
378+
function getCurrentMode() {
379+
return PreferencesManager.get(PREFERENCE_LIVE_PREVIEW_MODE) || _getDefaultMode();
380+
}
381+
319382
/** Initialize LiveDevelopment */
320383
AppInit.appReady(function () {
321384
params.parse();
@@ -330,6 +393,15 @@ define(function main(require, exports, module) {
330393
_loadStyles();
331394
_updateHighlightCheckmark();
332395

396+
// init pro user status and listen for changes
397+
if (KernalModeTrust) {
398+
_updateProUserStatus();
399+
KernalModeTrust.EntitlementsManager.on(
400+
KernalModeTrust.EntitlementsManager.EVENT_ENTITLEMENTS_CHANGED,
401+
_updateProUserStatus
402+
);
403+
}
404+
333405
// update styles for UI status
334406
_status = [
335407
{ tooltip: Strings.LIVE_DEV_STATUS_TIP_NOT_CONNECTED, style: "warning" },
@@ -385,6 +457,11 @@ define(function main(require, exports, module) {
385457
}
386458
});
387459

460+
PreferencesManager.definePreference(PREFERENCE_LIVE_PREVIEW_MODE, "string", _getDefaultMode(), {
461+
description: StringUtils.format(Strings.LIVE_PREVIEW_MODE_PREFERENCE, "'preview'", "'highlight'", "'edit'"),
462+
values: ["preview", "highlight", "edit"]
463+
});
464+
388465
config.highlight = PreferencesManager.getViewState("livedevHighlight");
389466

390467
function setLivePreviewEditFeaturesActive(enabled) {
@@ -441,4 +518,6 @@ define(function main(require, exports, module) {
441518
exports.getLivePreviewDetails = MultiBrowserLiveDev.getLivePreviewDetails;
442519
exports.hideHighlight = MultiBrowserLiveDev.hideHighlight;
443520
exports.dismissLivePreviewBoxes = MultiBrowserLiveDev.dismissLivePreviewBoxes;
521+
exports.setMode = setMode;
522+
exports.getCurrentMode = getCurrentMode;
444523
});

appConfig.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ window.AppConfig = {
3333
"app_update_url": "https://updates.phcode.io/tauri/update-latest-experimental-build.json",
3434
"extensionTakedownURL": "https://updates.phcode.io/extension_takedown.json",
3535
"linting.enabled_by_default": true,
36-
"build_timestamp": "2025-11-20T15:46:31.860Z",
36+
"build_timestamp": "2025-11-22T06:21:43.682Z",
3737
"googleAnalyticsID": "G-P4HJFPDB76",
3838
"googleAnalyticsIDDesktop": "G-VE5BXWJ0HF",
3939
"mixPanelID": "49c4d164b592be2350fc7af06a259bf3",
@@ -45,7 +45,7 @@ window.AppConfig = {
4545
"bugsnagEnv": "development"
4646
},
4747
"name": "Phoenix Code",
48-
"version": "4.1.2-21722",
48+
"version": "4.1.2-21725",
4949
"apiVersion": "4.1.2",
5050
"homepage": "https://core.ai",
5151
"issues": {

assets/default-project/en.zip

0 Bytes
Binary file not shown.

assets/sample-projects/HTML5.zip

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

assets/sample-projects/explore.zip

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)