Skip to content

Commit c030865

Browse files
committed
deploy: 606b7d0
1 parent 898513e commit c030865

Some content is hidden

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

63 files changed

+2389
-332
lines changed

appConfig.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ window.AppConfig = {
3131
"app_notification_url": "assets/notifications/dev/",
3232
"app_update_url": "https://updates.phcode.io/tauri/update-latest-experimental-build.json",
3333
"linting.enabled_by_default": true,
34-
"build_timestamp": "2025-09-09T14:27:02.477Z",
34+
"build_timestamp": "2025-09-10T09:22:02.772Z",
3535
"googleAnalyticsID": "G-P4HJFPDB76",
3636
"googleAnalyticsIDDesktop": "G-VE5BXWJ0HF",
3737
"mixPanelID": "49c4d164b592be2350fc7af06a259bf3",
@@ -43,7 +43,7 @@ window.AppConfig = {
4343
"bugsnagEnv": "development"
4444
},
4545
"name": "Phoenix Code",
46-
"version": "4.1.2-21425",
46+
"version": "4.1.2-21429",
4747
"apiVersion": "4.1.2",
4848
"homepage": "https://core.ai",
4949
"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.

brackets-min.js

Lines changed: 226 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -167359,7 +167359,11 @@ define("services/login-service", function (require, exports, module) {
167359167359
require("./setup-login-service"); // this adds loginService to KernalModeTrust
167360167360
require("./promotions");
167361167361

167362+
const Metrics = require("utils/Metrics");
167363+
const LoginUtils = require("./login-utils");
167364+
167362167365
const MS_IN_DAY = 10 * 24 * 60 * 60 * 1000;
167366+
const TEN_MINUTES = 10 * 60 * 1000;
167363167367

167364167368
const KernalModeTrust = window.KernalModeTrust;
167365167369
if(!KernalModeTrust){
@@ -167375,6 +167379,25 @@ define("services/login-service", function (require, exports, module) {
167375167379
// Cached entitlements data
167376167380
let cachedEntitlements = null;
167377167381

167382+
// Last recorded state for entitlements monitoring
167383+
let lastRecordedState = null;
167384+
167385+
// Debounced trigger for entitlements changed
167386+
let entitlementsChangedTimer = null;
167387+
167388+
function _debounceEntitlementsChanged() {
167389+
if (entitlementsChangedTimer) {
167390+
// already scheduled, skip
167391+
return;
167392+
}
167393+
167394+
entitlementsChangedTimer = setTimeout(() => {
167395+
LoginService.trigger(EVENT_ENTITLEMENTS_CHANGED);
167396+
entitlementsChangedTimer = null;
167397+
}, 1000); // atmost 1 entitlement changed event will be triggered in a second
167398+
}
167399+
167400+
167378167401
/**
167379167402
* Get entitlements from API or cache
167380167403
* Returns null if user is not logged in
@@ -167428,7 +167451,7 @@ define("services/login-service", function (require, exports, module) {
167428167451

167429167452
// Trigger event if entitlements changed
167430167453
if (entitlementsChanged) {
167431-
LoginService.trigger(EVENT_ENTITLEMENTS_CHANGED, result);
167454+
_debounceEntitlementsChanged();
167432167455
}
167433167456

167434167457
return cachedEntitlements;
@@ -167448,12 +167471,43 @@ define("services/login-service", function (require, exports, module) {
167448167471
function clearEntitlements() {
167449167472
if (cachedEntitlements) {
167450167473
cachedEntitlements = null;
167474+
_debounceEntitlementsChanged();
167475+
}
167476+
}
167477+
167451167478

167452-
// Trigger event when entitlements are cleared
167453-
if (LoginService.trigger) {
167454-
LoginService.trigger(EVENT_ENTITLEMENTS_CHANGED, null);
167479+
/**
167480+
* Start the 10-minute interval timer for monitoring entitlements
167481+
*/
167482+
function startEntitlementsMonitor() {
167483+
setInterval(async () => {
167484+
try {
167485+
const current = await getEffectiveEntitlements(false); // Get effective entitlements
167486+
167487+
// Check if we need to refresh
167488+
const expiredPlanName = LoginUtils.validTillExpired(current, lastRecordedState);
167489+
const hasChanged = LoginUtils.haveEntitlementsChanged(current, lastRecordedState);
167490+
167491+
if (expiredPlanName || hasChanged) {
167492+
console.log(`Entitlements monitor detected changes, Expired: ${expiredPlanName},` +
167493+
`changed: ${hasChanged} refreshing...`);
167494+
Metrics.countEvent(Metrics.EVENT_TYPE.PRO, "entRefresh",
167495+
expiredPlanName ? "exp_"+expiredPlanName : "changed");
167496+
await getEffectiveEntitlements(true); // Force refresh
167497+
// if not logged in, the getEffectiveEntitlements will not trigger change even if some trial
167498+
// entitlements changed. so we trigger a change anyway here. The debounce will take care of
167499+
// multi fire and we are ok with multi fire 1 second apart.
167500+
_debounceEntitlementsChanged();
167501+
}
167502+
167503+
// Update last recorded state
167504+
lastRecordedState = current;
167505+
} catch (error) {
167506+
console.error('Entitlements monitor error:', error);
167455167507
}
167456-
}
167508+
}, TEN_MINUTES);
167509+
167510+
console.log('Entitlements monitor started (10-minute interval)');
167457167511
}
167458167512

167459167513
/**
@@ -167529,7 +167583,8 @@ define("services/login-service", function (require, exports, module) {
167529167583
* @example
167530167584
* // Listen for entitlements changes
167531167585
* const LoginService = window.KernelModeTrust.loginService;
167532-
* LoginService.on(LoginService.EVENT_ENTITLEMENTS_CHANGED, (entitlements) => {
167586+
* LoginService.on(LoginService.EVENT_ENTITLEMENTS_CHANGED, async() => {
167587+
* const entitlements = await LoginService.getEffectiveEntitlements();
167533167588
* console.log('Entitlements changed:', entitlements);
167534167589
* // Update UI based on new entitlements
167535167590
* });
@@ -167561,38 +167616,20 @@ define("services/login-service", function (require, exports, module) {
167561167616
if (serverEntitlements.plan.paidSubscriber) {
167562167617
// Already a paid subscriber, return as-is
167563167618
return serverEntitlements;
167564-
} else {
167565-
// Enhance entitlements for trial user
167566-
return {
167567-
...serverEntitlements,
167568-
plan: {
167569-
...serverEntitlements.plan,
167570-
paidSubscriber: true,
167571-
name: brackets.config.main_pro_plan
167572-
},
167573-
isInProTrial: true,
167574-
trialDaysRemaining: trialDaysRemaining,
167575-
entitlements: {
167576-
...serverEntitlements.entitlements,
167577-
liveEdit: {
167578-
activated: true,
167579-
subscribeURL: brackets.config.purchase_url,
167580-
upgradeToPlan: brackets.config.main_pro_plan,
167581-
validTill: Date.now() + trialDaysRemaining * MS_IN_DAY
167582-
}
167583-
}
167584-
};
167585167619
}
167586-
} else {
167587-
// Non-logged-in user with trial - return synthetic entitlements
167620+
// Enhance entitlements for trial user
167588167621
return {
167622+
...serverEntitlements,
167589167623
plan: {
167624+
...serverEntitlements.plan,
167590167625
paidSubscriber: true,
167591-
name: brackets.config.main_pro_plan
167626+
name: brackets.config.main_pro_plan,
167627+
validTill: Date.now() + trialDaysRemaining * MS_IN_DAY
167592167628
},
167593167629
isInProTrial: true,
167594167630
trialDaysRemaining: trialDaysRemaining,
167595167631
entitlements: {
167632+
...serverEntitlements.entitlements,
167596167633
liveEdit: {
167597167634
activated: true,
167598167635
subscribeURL: brackets.config.purchase_url,
@@ -167602,15 +167639,172 @@ define("services/login-service", function (require, exports, module) {
167602167639
}
167603167640
};
167604167641
}
167642+
167643+
// Non-logged-in user with trial - return synthetic entitlements
167644+
return {
167645+
plan: {
167646+
paidSubscriber: true,
167647+
name: brackets.config.main_pro_plan,
167648+
validTill: Date.now() + trialDaysRemaining * MS_IN_DAY
167649+
},
167650+
isInProTrial: true,
167651+
trialDaysRemaining: trialDaysRemaining,
167652+
entitlements: {
167653+
liveEdit: {
167654+
activated: true,
167655+
subscribeURL: brackets.config.purchase_url,
167656+
upgradeToPlan: brackets.config.main_pro_plan,
167657+
validTill: Date.now() + trialDaysRemaining * MS_IN_DAY
167658+
}
167659+
}
167660+
};
167605167661
}
167606167662

167607167663
// Add functions to secure exports
167608167664
LoginService.getEntitlements = getEntitlements;
167609167665
LoginService.getEffectiveEntitlements = getEffectiveEntitlements;
167610167666
LoginService.clearEntitlements = clearEntitlements;
167611167667
LoginService.EVENT_ENTITLEMENTS_CHANGED = EVENT_ENTITLEMENTS_CHANGED;
167668+
167669+
// Start the entitlements monitor timer
167670+
startEntitlementsMonitor();
167612167671
});
167613167672

167673+
/*
167674+
* GNU AGPL-3.0 License
167675+
*
167676+
* Copyright (c) 2021 - present core.ai . All rights reserved.
167677+
*
167678+
* This program is free software: you can redistribute it and/or modify it under
167679+
* the terms of the GNU Affero General Public License as published by the Free
167680+
* Software Foundation, either version 3 of the License, or (at your option) any later version.
167681+
*
167682+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
167683+
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
167684+
* See the GNU Affero General Public License for more details.
167685+
*
167686+
* You should have received a copy of the GNU Affero General Public License
167687+
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
167688+
*
167689+
*/
167690+
167691+
/**
167692+
* Login Service Utilities
167693+
*
167694+
* This module contains utility functions for login service operations,
167695+
* including entitlements expiration checking and change detection.
167696+
*/
167697+
167698+
define("services/login-utils", function (require, exports, module) {
167699+
167700+
/**
167701+
* Check if any validTill time has expired
167702+
*
167703+
* @param {Object|null} entitlements - Current entitlements object
167704+
* @param {Object|null} lastRecordedEntitlement - Previously recorded entitlements
167705+
* @returns {string|null} - Name of expired plan/entitlement or null if none expired
167706+
*/
167707+
function validTillExpired(entitlements, lastRecordedEntitlement) {
167708+
if (!entitlements) {
167709+
return null;
167710+
}
167711+
167712+
const now = Date.now();
167713+
167714+
function isNewlyExpired(validTill, lastValidTill) {
167715+
return (
167716+
validTill &&
167717+
validTill < now && // expired now
167718+
(!lastValidTill || lastValidTill >= now) // but wasn't expired before
167719+
);
167720+
}
167721+
167722+
// Check plan validTill
167723+
if (entitlements.plan) {
167724+
const validTill = entitlements.plan.validTill;
167725+
const lastValidTill = (lastRecordedEntitlement && lastRecordedEntitlement.plan)
167726+
? lastRecordedEntitlement.plan.validTill
167727+
: null;
167728+
167729+
if (isNewlyExpired(validTill, lastValidTill)) {
167730+
return entitlements.plan.name || brackets.config.main_pro_plan;
167731+
}
167732+
}
167733+
167734+
// Check entitlements validTill
167735+
if (entitlements.entitlements) {
167736+
for (const key in entitlements.entitlements) {
167737+
const entitlement = entitlements.entitlements[key];
167738+
if (!entitlement) {
167739+
continue;
167740+
}
167741+
167742+
const validTill = entitlement.validTill;
167743+
const lastValidTill = (lastRecordedEntitlement &&
167744+
lastRecordedEntitlement.entitlements &&
167745+
lastRecordedEntitlement.entitlements[key])
167746+
? lastRecordedEntitlement.entitlements[key].validTill
167747+
: null;
167748+
167749+
if (isNewlyExpired(validTill, lastValidTill)) {
167750+
return key;
167751+
}
167752+
}
167753+
}
167754+
167755+
return null;
167756+
}
167757+
167758+
/**
167759+
* Check if entitlements have changed from last recorded state
167760+
*
167761+
* @param {Object|null} current - Current entitlements object
167762+
* @param {Object|null} last - Last recorded entitlements object
167763+
* @returns {boolean} - True if entitlements have changed, false otherwise
167764+
*/
167765+
function haveEntitlementsChanged(current, last) {
167766+
if (!last && !current) {
167767+
return false;
167768+
}
167769+
if ((!last && current) || (!current && last)) {
167770+
return true;
167771+
}
167772+
if ((!last.entitlements && current.entitlements) || (!current.entitlements && last.entitlements)) {
167773+
return true;
167774+
}
167775+
167776+
// Check paidSubscriber changes
167777+
const currentPaidSub = current.plan && current.plan.paidSubscriber;
167778+
const lastPaidSub = last.plan && last.plan.paidSubscriber;
167779+
if (currentPaidSub !== lastPaidSub) {
167780+
return true;
167781+
}
167782+
167783+
// Check plan name changes
167784+
const currentPlanName = current.plan && current.plan.name;
167785+
const lastPlanName = last.plan && last.plan.name;
167786+
if (currentPlanName !== lastPlanName) {
167787+
return true;
167788+
}
167789+
167790+
// Check entitlement activations
167791+
if (current.entitlements && last.entitlements) {
167792+
for (const key of Object.keys(current.entitlements)) {
167793+
const currentActivated = current.entitlements[key] && current.entitlements[key].activated;
167794+
const lastActivated = last.entitlements[key] && last.entitlements[key].activated;
167795+
if (currentActivated !== lastActivated) {
167796+
return true;
167797+
}
167798+
}
167799+
}
167800+
167801+
return false;
167802+
}
167803+
167804+
// Export functions
167805+
exports.validTillExpired = validTillExpired;
167806+
exports.haveEntitlementsChanged = haveEntitlementsChanged;
167807+
});
167614167808
/*
167615167809
* GNU AGPL-3.0 License
167616167810
*
@@ -168871,8 +169065,8 @@ define("services/promotions", function (require, exports, module) {
168871169065

168872169066
// Also trigger entitlements changed event since effective entitlements have changed
168873169067
// This allows UI components to update based on the new trial status
168874-
const effectiveEntitlements = await LoginService.getEffectiveEntitlements();
168875-
LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED, effectiveEntitlements);
169068+
await LoginService.getEffectiveEntitlements();
169069+
LoginService.trigger(LoginService.EVENT_ENTITLEMENTS_CHANGED);
168876169070
}
168877169071

168878169072
function _isAnyDialogsVisible() {

0 commit comments

Comments
 (0)