From b9d57b2112de48f5a2a5396a3347d9366092960e Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Wed, 22 May 2024 23:47:32 +0800 Subject: [PATCH 01/18] fix: avoid import action break subscription restriction --- src/components/app.jsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/components/app.jsx b/src/components/app.jsx index dccacf88..97abe97f 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -859,6 +859,10 @@ BookLibService.Borrow(id) { trackEvent('ui', LocalStorageKeys.LOGIN_AND_SAVE_MESSAGE_SEEN, 'local'); } var isNewItem = !this.state.currentItem.id; + if (isNewItem && this.checkItemsLimit()) { + this.proBtnClickHandler(); + return; + } this.state.currentItem.id = this.state.currentItem.id || 'item-' + generateRandomId(); await this.setState({ @@ -1300,6 +1304,14 @@ BookLibService.Borrow(id) { * Called from inside ask-to-import-modal */ importCreationsAndSettingsIntoApp() { + if (!this.checkItemsLimit()) { + mixpanel.track({ + event: 'Free Limit', + category: '3 diagrams limit', + label: 'ImportCreations', + }); + return; + } this.mergeImportedItems(this.oldSavedItems).then(() => { trackEvent('fn', 'oldItemsImported'); this.dontAskToImportAnymore(); From e9fd313fdca7a842dce07e2e225dfca21851664f Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 14:18:52 +0800 Subject: [PATCH 02/18] feat: check items limit when saving --- src/components/SavedItemPane.jsx | 1 + src/components/app.jsx | 70 ++++++++++++++++++++++++-------- src/db.js | 5 +++ src/itemService.js | 5 +++ 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/components/SavedItemPane.jsx b/src/components/SavedItemPane.jsx index 3e606c7c..54991a4c 100644 --- a/src/components/SavedItemPane.jsx +++ b/src/components/SavedItemPane.jsx @@ -13,6 +13,7 @@ export default class SavedItemPane extends Component { } componentWillUpdate(nextProps) { + console.log('feng componentWillUpdate'); if (this.props.items !== nextProps.items) { this.items = Object.values(nextProps.items); this.items.sort(function (a, b) { diff --git a/src/components/app.jsx b/src/components/app.jsx index 97abe97f..2693b8cd 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -137,6 +137,7 @@ export default class App extends Component { // window.zd_libraryBtHander = this.openAddLibrary.bind(this) } firebase.auth().onAuthStateChanged(async (user) => { + console.debug('feng onAuthStateChanged'); await this.setState({ isLoginModalOpen: false }); if (user) { log('You are -> ', user); @@ -455,6 +456,19 @@ BookLibService.Borrow(id) { return d.promise; } + alertIfExceedItemsLimit() { + const r = this.checkItemsLimit(); + if (!r) this.alertItemsLimit(); + return r; + } + + alertItemsLimit() { + alert( + `You have ${Object.keys(this.state.user.items).length} diagrams, the limit is ${userService.isBasic() ? 20 : 3}. Upgrade now for more storage.`, + ); + this.proBtnClickHandler(); + } + checkItemsLimit() { if ( !this.state.user || @@ -465,11 +479,17 @@ BookLibService.Borrow(id) { ) { return true; } + return false; + } - alert( - `You have ${Object.keys(this.state.user.items).length} diagrams, the limit is ${userService.isBasic() ? 20 : 3}. Upgrade now for more storage.`, - ); - this.proBtnClickHandler(); + isNewItem(itemId) { + if (!itemId) return true; + const { user } = this.state; + if (user && user.items) { + const found = Object.keys(user.items).some((key) => itemId === key); + return !found; + } + return true; } saveBtnClickHandler() { @@ -482,8 +502,8 @@ BookLibService.Borrow(id) { ? 'saved' : 'new', ); - - if (!this.checkItemsLimit()) { + console.log('feng saveBtnClickHandler'); + if (!this.alertIfExceedItemsLimit()) { mixpanel.track({ event: 'Free Limit', category: '3 diagrams limit', @@ -546,6 +566,7 @@ BookLibService.Borrow(id) { var items = []; if ((window.user || window.zenumlDesktop) && !shouldFetchLocally) { items = await itemService.getAllItems(); + console.log(`feng fetchItems got items:${items.length}`); log('got items'); if (shouldSaveGlobally) { items.forEach((item) => { @@ -585,6 +606,7 @@ BookLibService.Borrow(id) { await this.setState({ isFetchingItems: true, }); + console.log('feng openSavedItemsPane'); this.fetchItems(true).then(async (items) => { await this.setState({ isFetchingItems: false, @@ -624,7 +646,7 @@ BookLibService.Borrow(id) { // Ctrl/⌘ + S if ((event.ctrlKey || event.metaKey) && event.keyCode === 83) { event.preventDefault(); - this.saveItem(); + this.saveItem(true); trackEvent('ui', 'saveItemKeyboardShortcut'); } // Ctrl/⌘ + Shift + 5 @@ -840,7 +862,8 @@ BookLibService.Borrow(id) { } // Save current item to storage - async saveItem() { + async saveItem(isManual = false) { + console.log('feng saveItem'); if ( !window.user && !window.localStorage[LocalStorageKeys.LOGIN_AND_SAVE_MESSAGE_SEEN] && @@ -858,13 +881,25 @@ BookLibService.Borrow(id) { } trackEvent('ui', LocalStorageKeys.LOGIN_AND_SAVE_MESSAGE_SEEN, 'local'); } - var isNewItem = !this.state.currentItem.id; - if (isNewItem && this.checkItemsLimit()) { - this.proBtnClickHandler(); + var isNewItem = this.isNewItem(this.state.currentItem.id); + let check = this.checkItemsLimit(); + console.log( + `feng saveItem checkItemsLimit:${check} isNewItem:${isNewItem}`, + ); + if (isNewItem && !check) { + if (isManual) this.alertItemsLimit(); return; } + console.log( + 'feng saveItem before currentItem.id', + this.state.currentItem.id, + ); this.state.currentItem.id = this.state.currentItem.id || 'item-' + generateRandomId(); + console.log( + 'feng saveItem after currentItem.id', + this.state.currentItem.id, + ); await this.setState({ isSaving: true, }); @@ -1062,7 +1097,8 @@ BookLibService.Borrow(id) { } async itemForkBtnClickHandler(item) { - if (!this.checkItemsLimit()) { + console.log('feng itemForkBtnClickHandler'); + if (!this.alertIfExceedItemsLimit()) { mixpanel.track({ event: 'Free Limit', category: '3 diagrams limit', @@ -1079,8 +1115,8 @@ BookLibService.Borrow(id) { async newBtnClickHandler() { mixpanel.track({ event: 'newBtnClick', category: 'ui' }); - - if (!this.checkItemsLimit()) { + console.log('feng newBtnClickHandler'); + if (!this.alertIfExceedItemsLimit()) { mixpanel.track({ event: 'Free Limit', category: '3 diagrams limit', @@ -1208,7 +1244,8 @@ BookLibService.Borrow(id) { } exportBtnClickHandler(e) { - if (!this.checkItemsLimit()) { + console.log('feng exportBtnClickHandler'); + if (!this.alertIfExceedItemsLimit()) { mixpanel.track({ event: 'Free Limit', category: '3 diagrams limit', @@ -1304,7 +1341,8 @@ BookLibService.Borrow(id) { * Called from inside ask-to-import-modal */ importCreationsAndSettingsIntoApp() { - if (!this.checkItemsLimit()) { + console.log('feng importCreationsAndSettingsIntoApp'); + if (!this.alertIfExceedItemsLimit()) { mixpanel.track({ event: 'Free Limit', category: '3 diagrams limit', diff --git a/src/db.js b/src/db.js index 32da1147..d4cc239f 100644 --- a/src/db.js +++ b/src/db.js @@ -123,6 +123,7 @@ import { log } from './utils'; } async function getUser(userId) { + console.log('feng db getUser'); const remoteDb = await getDb(); return remoteDb .doc(`users/${userId}`) @@ -135,7 +136,11 @@ import { log } from './utils'; merge: true, }, ); + //user.items value source const user = doc.data(); + console.log( + `feng db getUser user.items:${Object.keys(user.items).length}`, + ); Object.assign(window.user, user); return user; }); diff --git a/src/itemService.js b/src/itemService.js index e4dd4eb2..f63df5fe 100644 --- a/src/itemService.js +++ b/src/itemService.js @@ -20,6 +20,7 @@ if (window.zenumlDesktop) { async getUserItemIds() { if (window.user) { return new Promise((resolve) => { + console.log('feng getUserItemIds step1'); resolve(window.user.items || {}); }); } @@ -31,6 +32,7 @@ if (window.zenumlDesktop) { if (!doc.exists) { return {}; } + console.log('feng getUserItemIds step2'); return doc.data().items; }); }, @@ -39,6 +41,7 @@ if (window.zenumlDesktop) { var t = Date.now(); var d = deferred(); let itemIds = await this.getUserItemIds(); + console.log(`feng getAllItems itemIds:${Object.keys(itemIds).length}`); itemIds = Object.getOwnPropertyNames(itemIds || {}); log('itemids', itemIds); @@ -156,6 +159,7 @@ if (window.zenumlDesktop) { [`items.${id}`]: true, }); // Set these items on our cached user object too + console.log('feng saveItems'); window.user.items = window.user.items || {}; window.user.items[id] = true; } @@ -209,6 +213,7 @@ if (window.zenumlDesktop) { }) .then((arg) => { log(`Item ${itemId} set for user`, arg); + console.log('feng set user.items'); window.user.items = window.user.items || {}; window.user.items[itemId] = true; }) From 4a1ba99b07acb46eb53b0adefb6c33edbfd9e6de Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 16:02:46 +0800 Subject: [PATCH 03/18] refactor: add IPlan and plan instance --- src/services/planService.js | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/services/planService.js b/src/services/planService.js index 6a0859b9..d953c4bd 100644 --- a/src/services/planService.js +++ b/src/services/planService.js @@ -15,6 +15,51 @@ const getProductByPlanType = (planType) => { return product; }; +// 定义接口 +const IPlan = { + getMaxItemsCount: () => {}, + canCustomizeCSS: () => {}, + getProductId: () => {}, + getPlanType: () => {}, +}; + +const getPlanByType = (planType) => { + const planMap = { + free: { + getMaxItemsCount: () => 3, + canCustomizeCSS: () => false, + getProductId: () => '', + getPlanType: () => 'free', + }, + 'basic-monthly': { + getMaxItemsCount: () => 20, + canCustomizeCSS: () => false, + getProductId: () => config.paddleProductBasicMonthly, + getPlanType: () => 'basic-monthly', + }, + 'plus-monthly': { + getMaxItemsCount: () => 999999, + canCustomizeCSS: () => true, + getProductId: () => config.paddleProductPlusMonthly, + getPlanType: () => 'plus-monthly', + }, + 'basic-yearly': { + getMaxItemsCount: () => 20, + canCustomizeCSS: () => false, + getProductId: () => config.paddleProductBasicYearly, + getPlanType: () => 'basic-yearly', + }, + 'plus-yearly': { + getMaxItemsCount: () => 999999, + canCustomizeCSS: () => true, + getProductId: () => config.paddleProductPlusYearly, + getPlanType: () => 'plus-yearly', + }, + }; + + return planMap[planType] || planMap['free']; +}; export default { getProductByPlanType: getProductByPlanType, + getPlanByType: getPlanByType, }; From e1203fd072774aabd0ebe2d6aaec39ec08df89aa Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 16:05:10 +0800 Subject: [PATCH 04/18] refactor: using IPlan to check items limit --- src/components/app.jsx | 20 +++++++++----------- src/services/user_service.js | 4 ++++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/components/app.jsx b/src/components/app.jsx index 2693b8cd..aafc7b52 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -463,23 +463,21 @@ BookLibService.Borrow(id) { } alertItemsLimit() { + var plan = userService.getPlan(); alert( - `You have ${Object.keys(this.state.user.items).length} diagrams, the limit is ${userService.isBasic() ? 20 : 3}. Upgrade now for more storage.`, + `You have ${this.getUserItemsCount()} diagrams, the limit is ${plan.getMaxItemsCount()}. Upgrade now for more storage.`, ); this.proBtnClickHandler(); } + getUserItemsCount() { + if (!this.state.user || !this.state.user.items) return 0; + return Object.keys(this.state.user.items).length; + } + checkItemsLimit() { - if ( - !this.state.user || - !this.state.user.items || - Object.keys(this.state.user.items).length <= 3 || - userService.isPlusOrAdvanced() || - (Object.keys(this.state.user.items).length <= 20 && userService.isBasic()) - ) { - return true; - } - return false; + var currentItemsCount = this.getUserItemsCount(); + return userService.getPlan().getMaxItemsCount() >= currentItemsCount; } isNewItem(itemId) { diff --git a/src/services/user_service.js b/src/services/user_service.js index 2f0fe4b8..cafba66c 100644 --- a/src/services/user_service.js +++ b/src/services/user_service.js @@ -1,3 +1,4 @@ +import planService from './planService'; const user = () => window.user; const subscription = () => user() && user().subscription; @@ -26,6 +27,9 @@ export default { const currentSubscription = subscription(); return getPlanTypeFromPassthrough(currentSubscription.passthrough); }, + getPlan: function () { + return planService.getPlanByType(this.getPlanType()); + }, }; // Compatible with previous pro users, before subscription.passthrough only stored userId From a87a950ec6d762b4026c0237de6c6cf31e09478b Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 16:06:12 +0800 Subject: [PATCH 05/18] refactor: using IPlan to check if can edit css --- src/components/ContentWrap.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ContentWrap.jsx b/src/components/ContentWrap.jsx index 63902aa1..33f95c0c 100644 --- a/src/components/ContentWrap.jsx +++ b/src/components/ContentWrap.jsx @@ -804,7 +804,7 @@ export default class ContentWrap extends Component { onCSSActiviation() { if (!window.user) { this.props.onLogin(); - } else if (userService.isPlusOrAdvanced()) { + } else if (userService.getPlan().canCustomizeCSS()) { return true; } else { this.props.onProFeature(); From 4544cfac019ae159d9f035dcefde6db85ee7b4bb Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 16:21:51 +0800 Subject: [PATCH 06/18] refactor: remove useless function in user_service --- src/services/user_service.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/services/user_service.js b/src/services/user_service.js index cafba66c..01128ca2 100644 --- a/src/services/user_service.js +++ b/src/services/user_service.js @@ -13,15 +13,6 @@ export default { subscription().status === 'trialing') ); }, - isBasic: function () { - return this.getPlanType().includes('basic'); - }, - isPlus: function () { - return this.getPlanType().includes('plus'); - }, - isPlusOrAdvanced: function () { - return this.isPlus(); - }, getPlanType: function () { if (!this.isSubscribed()) return 'free'; const currentSubscription = subscription(); From 4ea340297998106ad4c3225d4a031b40761d141d Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 16:27:32 +0800 Subject: [PATCH 07/18] refactor: replace getProductByPlanType with IPlan --- src/components/subscription/UpgradeLink.jsx | 3 +-- src/services/planService.js | 15 --------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/components/subscription/UpgradeLink.jsx b/src/components/subscription/UpgradeLink.jsx index dc23be53..b8524a44 100644 --- a/src/components/subscription/UpgradeLink.jsx +++ b/src/components/subscription/UpgradeLink.jsx @@ -1,5 +1,4 @@ import planService from '../../services/planService'; -import userService from '../../services/user_service'; const UpgradeLink = (props) => { const checkout = (e) => { @@ -7,7 +6,7 @@ const UpgradeLink = (props) => { props.preActionCallback(); Paddle.Checkout.open({ - product: planService.getProductByPlanType(props.planType), + product: planService.getPlanByType(props.planType).getProductId(), email: props.userEmail, passthrough: JSON.stringify({ userId: props.userId, diff --git a/src/services/planService.js b/src/services/planService.js index d953c4bd..9db3eae4 100644 --- a/src/services/planService.js +++ b/src/services/planService.js @@ -2,20 +2,6 @@ import config from './configuration'; //TODO(refactor): It is necessary to integrate more plan-related logic into this module. -const getProductByPlanType = (planType) => { - const productMap = { - 'basic-monthly': config.paddleProductBasicMonthly, - 'plus-monthly': config.paddleProductPlusMonthly, - 'basic-yearly': config.paddleProductBasicYearly, - 'plus-yearly': config.paddleProductPlusYearly, - }; - - const product = productMap[planType] || ''; - console.debug('getProductByPlanType', planType, product); - return product; -}; - -// 定义接口 const IPlan = { getMaxItemsCount: () => {}, canCustomizeCSS: () => {}, @@ -60,6 +46,5 @@ const getPlanByType = (planType) => { return planMap[planType] || planMap['free']; }; export default { - getProductByPlanType: getProductByPlanType, getPlanByType: getPlanByType, }; From cd96746b2891f7134b0fda3a80bf54fff16fe444 Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 16:45:04 +0800 Subject: [PATCH 08/18] refactor: move 'checkPlanTypeFromUserSubscription' from user service to plan service --- src/services/planService.js | 23 +++++++++++++++++++++++ src/services/user_service.js | 24 ++++-------------------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/services/planService.js b/src/services/planService.js index 9db3eae4..6fd9e6bb 100644 --- a/src/services/planService.js +++ b/src/services/planService.js @@ -45,6 +45,29 @@ const getPlanByType = (planType) => { return planMap[planType] || planMap['free']; }; + +const checkPlanTypeFromUserSubscription = ( + isSubscribed, + getSubscriptionPassthroughFunc, +) => { + if (!isSubscribed) return 'free'; + // Compatible with previous pro users, before subscription.passthrough only stored userId + const passthrough = getSubscriptionPassthroughFunc(); + return isJSONString(passthrough) + ? JSON.parse(passthrough).planType + : 'basic-monthly'; +}; + +function isJSONString(str) { + try { + JSON.parse(str); + return true; + } catch (e) { + return false; + } +} + export default { + checkPlanTypeFromUserSubscription: checkPlanTypeFromUserSubscription, getPlanByType: getPlanByType, }; diff --git a/src/services/user_service.js b/src/services/user_service.js index 01128ca2..c427b5bc 100644 --- a/src/services/user_service.js +++ b/src/services/user_service.js @@ -6,7 +6,6 @@ export default { user: user, subscription: subscription, isSubscribed: function () { - //console.debug('subscription', subscription()); return ( subscription() && (subscription().status === 'active' || @@ -14,27 +13,12 @@ export default { ); }, getPlanType: function () { - if (!this.isSubscribed()) return 'free'; - const currentSubscription = subscription(); - return getPlanTypeFromPassthrough(currentSubscription.passthrough); + return planService.checkPlanTypeFromUserSubscription( + this.isSubscribed(), + () => subscription().passthrough, + ); }, getPlan: function () { return planService.getPlanByType(this.getPlanType()); }, }; - -// Compatible with previous pro users, before subscription.passthrough only stored userId -function getPlanTypeFromPassthrough(passthrough) { - return isJSONString(passthrough) - ? JSON.parse(passthrough).planType - : 'basic-monthly'; -} - -function isJSONString(str) { - try { - JSON.parse(str); - return true; - } catch (e) { - return false; - } -} From d616102c1cc909222d24df8c719e38cddf07186b Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 17:40:29 +0800 Subject: [PATCH 09/18] refactor: improve naming and adjust corresponding decision logic for 'alertAndTrackIfExceedItemsLimit' --- src/components/app.jsx | 67 ++++++++++++------------------------------ 1 file changed, 19 insertions(+), 48 deletions(-) diff --git a/src/components/app.jsx b/src/components/app.jsx index aafc7b52..953fbbae 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -456,16 +456,23 @@ BookLibService.Borrow(id) { return d.promise; } - alertIfExceedItemsLimit() { - const r = this.checkItemsLimit(); - if (!r) this.alertItemsLimit(); - return r; + alertAndTrackIfExceedItemsLimit(userActionName) { + const exceed = !this.checkItemsLimit(); + if (exceed) { + this.alertItemsLimit(); + var plan = userService.getPlan(); + mixpanel.track({ + event: `${plan.getPlanType()} Limit`, + category: `${plan.getMaxItemsCount()} diagrams limit`, + label: userActionName, + }); + } + return exceed; } alertItemsLimit() { - var plan = userService.getPlan(); alert( - `You have ${this.getUserItemsCount()} diagrams, the limit is ${plan.getMaxItemsCount()}. Upgrade now for more storage.`, + `You have ${this.getUserItemsCount()} diagrams, the limit is ${userService.getPlan().getMaxItemsCount()}. Upgrade now for more storage.`, ); this.proBtnClickHandler(); } @@ -476,8 +483,7 @@ BookLibService.Borrow(id) { } checkItemsLimit() { - var currentItemsCount = this.getUserItemsCount(); - return userService.getPlan().getMaxItemsCount() >= currentItemsCount; + return userService.getPlan().getMaxItemsCount() >= this.getUserItemsCount(); } isNewItem(itemId) { @@ -501,14 +507,7 @@ BookLibService.Borrow(id) { : 'new', ); console.log('feng saveBtnClickHandler'); - if (!this.alertIfExceedItemsLimit()) { - mixpanel.track({ - event: 'Free Limit', - category: '3 diagrams limit', - label: 'Save', - }); - return; - } + if (this.alertAndTrackIfExceedItemsLimit('Save')) return; if (this.state.user || window.zenumlDesktop) { this.saveItem(); @@ -1096,14 +1095,7 @@ BookLibService.Borrow(id) { async itemForkBtnClickHandler(item) { console.log('feng itemForkBtnClickHandler'); - if (!this.alertIfExceedItemsLimit()) { - mixpanel.track({ - event: 'Free Limit', - category: '3 diagrams limit', - label: 'Fork', - }); - return; - } + if (this.alertAndTrackIfExceedItemsLimit('Fork')) return; await this.toggleSavedItemsPane(); setTimeout(() => { @@ -1114,14 +1106,7 @@ BookLibService.Borrow(id) { async newBtnClickHandler() { mixpanel.track({ event: 'newBtnClick', category: 'ui' }); console.log('feng newBtnClickHandler'); - if (!this.alertIfExceedItemsLimit()) { - mixpanel.track({ - event: 'Free Limit', - category: '3 diagrams limit', - label: 'New', - }); - return; - } + if (this.alertAndTrackIfExceedItemsLimit('New')) return; if (this.state.unsavedEditCount) { var shouldDiscard = confirm( @@ -1243,14 +1228,7 @@ BookLibService.Borrow(id) { exportBtnClickHandler(e) { console.log('feng exportBtnClickHandler'); - if (!this.alertIfExceedItemsLimit()) { - mixpanel.track({ - event: 'Free Limit', - category: '3 diagrams limit', - label: 'Fork', - }); - return; - } + if (this.alertAndTrackIfExceedItemsLimit('Export')) return; this.exportItems(); e.preventDefault(); @@ -1340,14 +1318,7 @@ BookLibService.Borrow(id) { */ importCreationsAndSettingsIntoApp() { console.log('feng importCreationsAndSettingsIntoApp'); - if (!this.alertIfExceedItemsLimit()) { - mixpanel.track({ - event: 'Free Limit', - category: '3 diagrams limit', - label: 'ImportCreations', - }); - return; - } + if (this.alertAndTrackIfExceedItemsLimit('Import')) return; this.mergeImportedItems(this.oldSavedItems).then(() => { trackEvent('fn', 'oldItemsImported'); this.dontAskToImportAnymore(); From 9345847506d6be51edd1348ae3605bd191af5c2c Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 18:27:19 +0800 Subject: [PATCH 10/18] refactor: remove unnecessary debugging logs --- src/components/SavedItemPane.jsx | 1 - src/components/app.jsx | 21 +-------------------- src/db.js | 4 ---- src/itemService.js | 5 ----- 4 files changed, 1 insertion(+), 30 deletions(-) diff --git a/src/components/SavedItemPane.jsx b/src/components/SavedItemPane.jsx index 54991a4c..3e606c7c 100644 --- a/src/components/SavedItemPane.jsx +++ b/src/components/SavedItemPane.jsx @@ -13,7 +13,6 @@ export default class SavedItemPane extends Component { } componentWillUpdate(nextProps) { - console.log('feng componentWillUpdate'); if (this.props.items !== nextProps.items) { this.items = Object.values(nextProps.items); this.items.sort(function (a, b) { diff --git a/src/components/app.jsx b/src/components/app.jsx index 953fbbae..0241a864 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -137,7 +137,6 @@ export default class App extends Component { // window.zd_libraryBtHander = this.openAddLibrary.bind(this) } firebase.auth().onAuthStateChanged(async (user) => { - console.debug('feng onAuthStateChanged'); await this.setState({ isLoginModalOpen: false }); if (user) { log('You are -> ', user); @@ -506,7 +505,6 @@ BookLibService.Borrow(id) { ? 'saved' : 'new', ); - console.log('feng saveBtnClickHandler'); if (this.alertAndTrackIfExceedItemsLimit('Save')) return; if (this.state.user || window.zenumlDesktop) { @@ -563,7 +561,6 @@ BookLibService.Borrow(id) { var items = []; if ((window.user || window.zenumlDesktop) && !shouldFetchLocally) { items = await itemService.getAllItems(); - console.log(`feng fetchItems got items:${items.length}`); log('got items'); if (shouldSaveGlobally) { items.forEach((item) => { @@ -603,7 +600,6 @@ BookLibService.Borrow(id) { await this.setState({ isFetchingItems: true, }); - console.log('feng openSavedItemsPane'); this.fetchItems(true).then(async (items) => { await this.setState({ isFetchingItems: false, @@ -860,7 +856,6 @@ BookLibService.Borrow(id) { // Save current item to storage async saveItem(isManual = false) { - console.log('feng saveItem'); if ( !window.user && !window.localStorage[LocalStorageKeys.LOGIN_AND_SAVE_MESSAGE_SEEN] && @@ -880,23 +875,13 @@ BookLibService.Borrow(id) { } var isNewItem = this.isNewItem(this.state.currentItem.id); let check = this.checkItemsLimit(); - console.log( - `feng saveItem checkItemsLimit:${check} isNewItem:${isNewItem}`, - ); + console.log(`saveItem checkItemsLimit:${check} isNewItem:${isNewItem}`); if (isNewItem && !check) { if (isManual) this.alertItemsLimit(); return; } - console.log( - 'feng saveItem before currentItem.id', - this.state.currentItem.id, - ); this.state.currentItem.id = this.state.currentItem.id || 'item-' + generateRandomId(); - console.log( - 'feng saveItem after currentItem.id', - this.state.currentItem.id, - ); await this.setState({ isSaving: true, }); @@ -1094,7 +1079,6 @@ BookLibService.Borrow(id) { } async itemForkBtnClickHandler(item) { - console.log('feng itemForkBtnClickHandler'); if (this.alertAndTrackIfExceedItemsLimit('Fork')) return; await this.toggleSavedItemsPane(); @@ -1105,7 +1089,6 @@ BookLibService.Borrow(id) { async newBtnClickHandler() { mixpanel.track({ event: 'newBtnClick', category: 'ui' }); - console.log('feng newBtnClickHandler'); if (this.alertAndTrackIfExceedItemsLimit('New')) return; if (this.state.unsavedEditCount) { @@ -1227,7 +1210,6 @@ BookLibService.Borrow(id) { } exportBtnClickHandler(e) { - console.log('feng exportBtnClickHandler'); if (this.alertAndTrackIfExceedItemsLimit('Export')) return; this.exportItems(); @@ -1317,7 +1299,6 @@ BookLibService.Borrow(id) { * Called from inside ask-to-import-modal */ importCreationsAndSettingsIntoApp() { - console.log('feng importCreationsAndSettingsIntoApp'); if (this.alertAndTrackIfExceedItemsLimit('Import')) return; this.mergeImportedItems(this.oldSavedItems).then(() => { trackEvent('fn', 'oldItemsImported'); diff --git a/src/db.js b/src/db.js index d4cc239f..9482a50f 100644 --- a/src/db.js +++ b/src/db.js @@ -123,7 +123,6 @@ import { log } from './utils'; } async function getUser(userId) { - console.log('feng db getUser'); const remoteDb = await getDb(); return remoteDb .doc(`users/${userId}`) @@ -138,9 +137,6 @@ import { log } from './utils'; ); //user.items value source const user = doc.data(); - console.log( - `feng db getUser user.items:${Object.keys(user.items).length}`, - ); Object.assign(window.user, user); return user; }); diff --git a/src/itemService.js b/src/itemService.js index f63df5fe..e4dd4eb2 100644 --- a/src/itemService.js +++ b/src/itemService.js @@ -20,7 +20,6 @@ if (window.zenumlDesktop) { async getUserItemIds() { if (window.user) { return new Promise((resolve) => { - console.log('feng getUserItemIds step1'); resolve(window.user.items || {}); }); } @@ -32,7 +31,6 @@ if (window.zenumlDesktop) { if (!doc.exists) { return {}; } - console.log('feng getUserItemIds step2'); return doc.data().items; }); }, @@ -41,7 +39,6 @@ if (window.zenumlDesktop) { var t = Date.now(); var d = deferred(); let itemIds = await this.getUserItemIds(); - console.log(`feng getAllItems itemIds:${Object.keys(itemIds).length}`); itemIds = Object.getOwnPropertyNames(itemIds || {}); log('itemids', itemIds); @@ -159,7 +156,6 @@ if (window.zenumlDesktop) { [`items.${id}`]: true, }); // Set these items on our cached user object too - console.log('feng saveItems'); window.user.items = window.user.items || {}; window.user.items[id] = true; } @@ -213,7 +209,6 @@ if (window.zenumlDesktop) { }) .then((arg) => { log(`Item ${itemId} set for user`, arg); - console.log('feng set user.items'); window.user.items = window.user.items || {}; window.user.items[itemId] = true; }) From 273330736b7b975aa3d90701106df3bc98f0d4cf Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Sat, 29 Jun 2024 18:28:41 +0800 Subject: [PATCH 11/18] refactor: add saveItem debug log --- src/components/app.jsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/components/app.jsx b/src/components/app.jsx index 0241a864..6107abab 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -874,9 +874,12 @@ BookLibService.Borrow(id) { trackEvent('ui', LocalStorageKeys.LOGIN_AND_SAVE_MESSAGE_SEEN, 'local'); } var isNewItem = this.isNewItem(this.state.currentItem.id); - let check = this.checkItemsLimit(); - console.log(`saveItem checkItemsLimit:${check} isNewItem:${isNewItem}`); - if (isNewItem && !check) { + const check = this.checkItemsLimit(); + var preventedSaving = isNewItem && !check; + console.debug( + `saveItem preventedSaving:${preventedSaving} user:${window.user} isManual:${isManual} checkItemsLimit:${check} isNewItem:${isNewItem}`, + ); + if (preventedSaving) { if (isManual) this.alertItemsLimit(); return; } From 1c66ce3c1edd64390d27f700a0e406a3718e46e0 Mon Sep 17 00:00:00 2001 From: danshuitaihejie <474182370@qq.com> Date: Tue, 2 Jul 2024 04:50:36 +0800 Subject: [PATCH 12/18] refactor: check isSubscribed by plan --- src/components/MainHeader.jsx | 2 +- src/components/subscription/SubscriptionAction.jsx | 5 +++-- src/services/planService.js | 5 +++++ src/services/user_service.js | 11 +++-------- .../ProductVersionLabel/ProductVersionLabel.js | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/MainHeader.jsx b/src/components/MainHeader.jsx index 0c187b69..75e3c20b 100644 --- a/src/components/MainHeader.jsx +++ b/src/components/MainHeader.jsx @@ -57,7 +57,7 @@ export function MainHeader(props) { mixpanel.track({ event: 'toLanguageGuide', category: 'ui' }); }; - const isSubscribed = userService.isSubscribed(); + const isSubscribed = userService.getPlan().isSubscribed(); return (